From bd7b149223f500914812464aa8f7053445007d32 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Wed, 4 Dec 2024 17:50:00 -0500 Subject: [PATCH] Remove proxy for interface --- .../InterfaceHolder.ts | 8 +- .../InternalSymbols.ts | 6 - .../convertWireToOsdkObjects/ObjectHolder.ts | 16 +- .../createOsdkInterface.test.ts | 9 +- .../createOsdkInterface.ts | 185 +++++------------- .../createOsdkObject.ts | 17 +- .../convertWireToOsdkObjects/getDollarLink.ts | 15 +- 7 files changed, 66 insertions(+), 190 deletions(-) diff --git a/packages/client/src/object/convertWireToOsdkObjects/InterfaceHolder.ts b/packages/client/src/object/convertWireToOsdkObjects/InterfaceHolder.ts index 3dbe22a68..7cd325c6e 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/InterfaceHolder.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/InterfaceHolder.ts @@ -23,15 +23,9 @@ import type { import type { ObjectHolder } from "./ObjectHolder.js"; /** @internal */ -export interface InterfaceHolderOwnProps< +export interface InterfaceHolder< Q extends FetchedObjectTypeDefinition, > { [UnderlyingOsdkObject]: Osdk & ObjectHolder; [InterfaceDefRef]: InterfaceMetadata; } - -/** @internal */ -export interface InterfaceHolder< - Q extends FetchedObjectTypeDefinition, -> extends InterfaceHolderOwnProps { -} diff --git a/packages/client/src/object/convertWireToOsdkObjects/InternalSymbols.ts b/packages/client/src/object/convertWireToOsdkObjects/InternalSymbols.ts index aff58c5fd..d9045fe37 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/InternalSymbols.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/InternalSymbols.ts @@ -31,12 +31,6 @@ export const InterfaceDefRef = Symbol( process.env.MODE !== "production" ? "InterfaceDefinition" : undefined, ); -/** A symbol for getting the raw data object off of the holder an osdk object proxy points to */ -/** @internal */ -export const RawObject = Symbol( - process.env.MODE !== "production" ? "RawObject" : undefined, -); - /** @internal */ export const ClientRef = Symbol( process.env.MODE !== "production" ? "ClientRef" : undefined, diff --git a/packages/client/src/object/convertWireToOsdkObjects/ObjectHolder.ts b/packages/client/src/object/convertWireToOsdkObjects/ObjectHolder.ts index b1ba16cfd..518f56a51 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/ObjectHolder.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/ObjectHolder.ts @@ -15,7 +15,6 @@ */ import type { Osdk } from "@osdk/api"; -import type { OntologyObjectV2 } from "@osdk/internal.foundry.core"; import type { MinimalClient } from "../../MinimalClientContext.js"; import type { FetchedObjectTypeDefinition } from "../../ontology/OntologyProvider.js"; import type { DollarAsFn } from "./getDollarAs.js"; @@ -23,25 +22,14 @@ import type { get$link } from "./getDollarLink.js"; import type { ClientRef, ObjectDefRef, - RawObject, UnderlyingOsdkObject, } from "./InternalSymbols.js"; /** @internal */ -export interface ObjectHolderPrototypeOwnProps { +export interface ObjectHolder { + readonly [UnderlyingOsdkObject]: Osdk; readonly [ObjectDefRef]: FetchedObjectTypeDefinition; readonly [ClientRef]: MinimalClient; readonly "$as": DollarAsFn; readonly "$link": ReturnType; } -/** @internal */ -export interface ObjectHolderOwnProperties { - [RawObject]: OntologyObjectV2; -} - -/** @internal */ -export interface ObjectHolder - extends ObjectHolderPrototypeOwnProps, ObjectHolderOwnProperties -{ - [UnderlyingOsdkObject]: Osdk; -} diff --git a/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.test.ts b/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.test.ts index 14ae7c362..df6ed28db 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.test.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.test.ts @@ -52,8 +52,7 @@ describe(createOsdkInterface, () => { status: "ACTIVE", } satisfies FetchedObjectTypeDefinition, }; - // underlying: Osdk & ObjectHolder, - // interfaceDef: InterfaceMetadata, + const iface = createOsdkInterface(underlying as any, { "apiName": "IFoo", displayName: "", @@ -114,8 +113,7 @@ describe(createOsdkInterface, () => { status: "ACTIVE", } satisfies FetchedObjectTypeDefinition, }; - // underlying: Osdk & ObjectHolder, - // interfaceDef: InterfaceMetadata, + const iface = createOsdkInterface(underlying as any, { "apiName": "a.IFoo", displayName: "", @@ -176,8 +174,7 @@ describe(createOsdkInterface, () => { status: "ACTIVE", } satisfies FetchedObjectTypeDefinition, }; - // underlying: Osdk & ObjectHolder, - // interfaceDef: InterfaceMetadata, + const iface = createOsdkInterface(underlying as any, { "apiName": "a.IFoo", displayName: "", diff --git a/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.ts b/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.ts index bc2c291fe..dfbac30ef 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/createOsdkInterface.ts @@ -14,14 +14,10 @@ * limitations under the License. */ -import type { InterfaceMetadata, Osdk, OsdkBase } from "@osdk/api"; +import type { InterfaceMetadata, Osdk } from "@osdk/api"; import { extractNamespace } from "../../internal/conversions/modernToLegacyWhereClause.js"; import type { FetchedObjectTypeDefinition } from "../../ontology/OntologyProvider.js"; -import { createSimpleCache } from "../SimpleCache.js"; -import type { - InterfaceHolder, - InterfaceHolderOwnProps, -} from "./InterfaceHolder.js"; +import type { InterfaceHolder } from "./InterfaceHolder.js"; import { InterfaceDefRef, ObjectDefRef, @@ -29,14 +25,6 @@ import { } from "./InternalSymbols.js"; import type { ObjectHolder } from "./ObjectHolder.js"; -const handlerCache = createSimpleCache< - InterfaceMetadata, - ProxyHandler & Osdk> ->( - new WeakMap(), - createInterfaceProxyHandler, -); - /** @internal */ export function createOsdkInterface< Q extends FetchedObjectTypeDefinition, @@ -44,127 +32,52 @@ export function createOsdkInterface< underlying: Osdk & ObjectHolder, interfaceDef: InterfaceMetadata, ) { - const interfaceHolder: InterfaceHolderOwnProps = Object.create(null, { - [UnderlyingOsdkObject]: { value: underlying }, - [InterfaceDefRef]: { value: interfaceDef }, - }); - - const handler = handlerCache.get(interfaceDef); - - const proxy = new Proxy>( - interfaceHolder as unknown as OsdkBase, // the wrapper doesn't contain everything obviously. we proxy - handler, + const [objApiNamespace] = extractNamespace(interfaceDef.apiName); + + return Object.freeze( + Object.defineProperties({}, { + // first to minimize hidden classes + [UnderlyingOsdkObject]: { value: underlying }, + + "$apiName": { value: interfaceDef.apiName, enumerable: true }, + "$as": { + value: underlying.$as, + enumerable: false, + }, + "$objectType": { + value: underlying.$objectType, + enumerable: "$objectType" in underlying, + }, + "$primaryKey": { + value: underlying.$primaryKey, + enumerable: "$primaryKey" in underlying, + }, + "$title": { + value: underlying.$title, + enumerable: "$title" in underlying, + }, + "$rid": { + value: (underlying as any).$rid, + enumerable: "$rid" in underlying, + }, + + [InterfaceDefRef]: { value: interfaceDef }, + + ...Object.fromEntries( + Object.keys(interfaceDef.properties).map(p => { + const objDef = underlying[ObjectDefRef]; + + const [apiNamespace, apiName] = extractNamespace(p); + + const targetPropName = objDef + .interfaceMap![interfaceDef.apiName][p]; + + return [apiNamespace === objApiNamespace ? apiName : p, { + enumerable: targetPropName in underlying, + value: underlying[targetPropName as keyof typeof underlying], + }]; + }), + ), + }) as InterfaceHolder & Osdk, ); - return proxy; -} - -function createInterfaceProxyHandler( - newDef: InterfaceMetadata, -): ProxyHandler & Osdk> { - return { - getOwnPropertyDescriptor(target, p) { - const underlying = target[UnderlyingOsdkObject]; - const objDef = underlying[ObjectDefRef]; - - switch (p) { - case UnderlyingOsdkObject: - case InterfaceDefRef: - return Reflect.getOwnPropertyDescriptor(target, p); - - case "$primaryKey": - case "$title": - case "$objectType": - case "$rid": - return p in underlying - ? { - value: underlying[p], - configurable: true, - enumerable: true, - } - : undefined; - - case "$apiName": - return { - enumerable: true, - configurable: true, - value: target[InterfaceDefRef].apiName, - }; - } - - const [objApiNamespace] = extractNamespace(newDef.apiName); - if (objApiNamespace != null) { - const [apiNamespace, apiName] = extractNamespace(p as string); - if (apiNamespace == null) { - p = `${objApiNamespace}.${apiName}`; - } - } - - if (newDef.properties[p as string] != null) { - return { - enumerable: true, - configurable: true, - value: underlying[ - objDef.interfaceMap![newDef.apiName][p as string] as any - ], - }; - } - }, - - ownKeys(target) { - const underlying = target[UnderlyingOsdkObject]; - const [objApiNamespace] = extractNamespace(newDef.apiName); - let propNames = Object.keys(newDef.properties); - - if (objApiNamespace != null) { - propNames = propNames.map(p => { - const [apiNamespace, apiName] = extractNamespace(p as string); - if (apiNamespace === objApiNamespace) { - p = apiName; - } - return p; - }); - } - - return [ - "$apiName", - "$objectType", - "$primaryKey", - ...(underlying["$rid"] ? ["$rid"] : []), - "$title", - UnderlyingOsdkObject, - InterfaceDefRef, - ...propNames, - ]; - }, - - get(target, p) { - const underlying = target[UnderlyingOsdkObject]; - switch (p) { - case InterfaceDefRef: - return newDef; - case "$apiName": - return newDef.apiName; - case "$as": - case UnderlyingOsdkObject: - case "$primaryKey": - case "$title": - case "$objectType": - case "$rid": - return underlying[p as string]; - } - - const [objApiNamespace] = extractNamespace(newDef.apiName); - if (objApiNamespace != null) { - const [apiNamespace, apiName] = extractNamespace(p as string); - if (apiNamespace == null) { - p = `${objApiNamespace}.${apiName}`; - } - } - - if (newDef.properties[p as string] != null) { - const objDef = target[UnderlyingOsdkObject][ObjectDefRef]; - return underlying[objDef.interfaceMap![newDef.apiName][p as string]]; - } - }, - }; } diff --git a/packages/client/src/object/convertWireToOsdkObjects/createOsdkObject.ts b/packages/client/src/object/convertWireToOsdkObjects/createOsdkObject.ts index d4f686666..d18fb69f5 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/createOsdkObject.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/createOsdkObject.ts @@ -27,13 +27,11 @@ import { get$link } from "./getDollarLink.js"; import { ClientRef, ObjectDefRef, - RawObject, UnderlyingOsdkObject, } from "./InternalSymbols.js"; import type { ObjectHolder } from "./ObjectHolder.js"; interface InternalOsdkInstance { - [RawObject]: OntologyObjectV2; [ObjectDefRef]: FetchedObjectTypeDefinition; [ClientRef]: MinimalClient; } @@ -62,7 +60,6 @@ const basePropDefs = { [UnderlyingOsdkObject]: this as any, [ObjectDefRef]: this[ObjectDefRef], [ClientRef]: this[ClientRef], - [RawObject]: this[RawObject], } as ObjectHolder); }, }, @@ -78,18 +75,13 @@ export function createOsdkObject< ): Osdk { // updates the object's "hidden class/map". Object.defineProperties(rawObj, { - [ObjectDefRef]: { value: objectDef, enumerable: false }, - [ClientRef]: { value: client, enumerable: false }, - [RawObject]: { - value: rawObj, - enumerable: false, - }, - ...basePropDefs, - [UnderlyingOsdkObject]: { enumerable: false, value: rawObj, }, + [ObjectDefRef]: { value: objectDef, enumerable: false }, + [ClientRef]: { value: client, enumerable: false }, + ...basePropDefs, }); // Assign the special values @@ -98,9 +90,6 @@ export function createOsdkObject< propKey in objectDef.properties && specialPropertyTypes.has(objectDef.properties[propKey].type) ) { - const rawValue = rawObj[propKey as any]; - const propDef = objectDef.properties[propKey as any]; - rawObj[propKey] = createSpecialProperty( client, objectDef, diff --git a/packages/client/src/object/convertWireToOsdkObjects/getDollarLink.ts b/packages/client/src/object/convertWireToOsdkObjects/getDollarLink.ts index 703d25216..70edc29e3 100644 --- a/packages/client/src/object/convertWireToOsdkObjects/getDollarLink.ts +++ b/packages/client/src/object/convertWireToOsdkObjects/getDollarLink.ts @@ -23,11 +23,12 @@ import type { } from "@osdk/api"; import { getWireObjectSet } from "../../objectSet/createObjectSet.js"; import { fetchSingle, fetchSingleWithErrors } from "../fetchSingle.js"; -import { ClientRef, ObjectDefRef, RawObject } from "./InternalSymbols.js"; -import type { - ObjectHolder, - ObjectHolderOwnProperties, -} from "./ObjectHolder.js"; +import { + ClientRef, + ObjectDefRef, + UnderlyingOsdkObject, +} from "./InternalSymbols.js"; +import type { ObjectHolder } from "./ObjectHolder.js"; /** @internal */ export function get$link( @@ -43,7 +44,7 @@ const DollarLinkProxyHandler: ProxyHandler> = { const { [ObjectDefRef]: objDef, [ClientRef]: client, - [RawObject]: rawObj, + [UnderlyingOsdkObject]: rawObj, } = target; const linkDef = objDef.links[p as string]; if (linkDef == null) { @@ -80,7 +81,7 @@ const DollarLinkProxyHandler: ProxyHandler> = { ownKeys( target: ObjectHolder, - ): ArrayLike { + ): ArrayLike | string> { return [...Object.keys(target[ObjectDefRef].links)]; },