jazz-tools 0.13.16 → 0.13.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +19 -0
  3. package/dist/{chunk-GIZWJXSR.js → chunk-ITSHLDQB.js} +731 -600
  4. package/dist/chunk-ITSHLDQB.js.map +1 -0
  5. package/dist/coValues/account.d.ts +5 -4
  6. package/dist/coValues/account.d.ts.map +1 -1
  7. package/dist/coValues/coFeed.d.ts +3 -3
  8. package/dist/coValues/coFeed.d.ts.map +1 -1
  9. package/dist/coValues/coList.d.ts +1 -0
  10. package/dist/coValues/coList.d.ts.map +1 -1
  11. package/dist/coValues/coMap.d.ts +4 -2
  12. package/dist/coValues/coMap.d.ts.map +1 -1
  13. package/dist/coValues/coPlainText.d.ts +2 -2
  14. package/dist/coValues/coPlainText.d.ts.map +1 -1
  15. package/dist/coValues/deepLoading.d.ts +1 -9
  16. package/dist/coValues/deepLoading.d.ts.map +1 -1
  17. package/dist/coValues/extensions/imageDef.d.ts.map +1 -1
  18. package/dist/coValues/group.d.ts.map +1 -1
  19. package/dist/coValues/inbox.d.ts.map +1 -1
  20. package/dist/coValues/interfaces.d.ts +4 -1
  21. package/dist/coValues/interfaces.d.ts.map +1 -1
  22. package/dist/implementation/createContext.d.ts.map +1 -1
  23. package/dist/implementation/refs.d.ts +5 -10
  24. package/dist/implementation/refs.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/internal.d.ts +1 -1
  27. package/dist/internal.d.ts.map +1 -1
  28. package/dist/subscribe/CoValueCoreSubscription.d.ts +14 -0
  29. package/dist/subscribe/CoValueCoreSubscription.d.ts.map +1 -0
  30. package/dist/subscribe/JazzError.d.ts +16 -0
  31. package/dist/subscribe/JazzError.d.ts.map +1 -0
  32. package/dist/subscribe/SubscriptionScope.d.ts +42 -0
  33. package/dist/subscribe/SubscriptionScope.d.ts.map +1 -0
  34. package/dist/subscribe/index.d.ts +21 -0
  35. package/dist/subscribe/index.d.ts.map +1 -0
  36. package/dist/subscribe/types.d.ts +12 -0
  37. package/dist/subscribe/types.d.ts.map +1 -0
  38. package/dist/subscribe/utils.d.ts +10 -0
  39. package/dist/subscribe/utils.d.ts.map +1 -0
  40. package/dist/testing.js +2 -2
  41. package/dist/testing.js.map +1 -1
  42. package/dist/tests/coMap.record.test.d.ts +2 -0
  43. package/dist/tests/coMap.record.test.d.ts.map +1 -0
  44. package/dist/tests/utils.d.ts +2 -2
  45. package/dist/tests/utils.d.ts.map +1 -1
  46. package/package.json +2 -2
  47. package/src/coValues/account.ts +43 -31
  48. package/src/coValues/coFeed.ts +28 -13
  49. package/src/coValues/coList.ts +13 -17
  50. package/src/coValues/coMap.ts +72 -80
  51. package/src/coValues/coPlainText.ts +13 -2
  52. package/src/coValues/deepLoading.ts +4 -277
  53. package/src/coValues/extensions/imageDef.ts +1 -7
  54. package/src/coValues/group.ts +7 -6
  55. package/src/coValues/inbox.ts +4 -11
  56. package/src/coValues/interfaces.ts +54 -111
  57. package/src/implementation/createContext.ts +3 -4
  58. package/src/implementation/invites.ts +2 -2
  59. package/src/implementation/refs.ts +30 -121
  60. package/src/internal.ts +1 -2
  61. package/src/subscribe/CoValueCoreSubscription.ts +71 -0
  62. package/src/subscribe/JazzError.ts +48 -0
  63. package/src/subscribe/SubscriptionScope.ts +523 -0
  64. package/src/subscribe/index.ts +82 -0
  65. package/src/subscribe/types.ts +7 -0
  66. package/src/subscribe/utils.ts +36 -0
  67. package/src/testing.ts +1 -1
  68. package/src/tests/ContextManager.test.ts +13 -9
  69. package/src/tests/coFeed.test.ts +104 -4
  70. package/src/tests/coList.test.ts +304 -115
  71. package/src/tests/coMap.record.test.ts +325 -0
  72. package/src/tests/coMap.test.ts +718 -645
  73. package/src/tests/coPlainText.test.ts +2 -2
  74. package/src/tests/createContext.test.ts +8 -8
  75. package/src/tests/deepLoading.test.ts +8 -34
  76. package/src/tests/groupsAndAccounts.test.ts +6 -4
  77. package/src/tests/subscribe.test.ts +357 -42
  78. package/src/tests/utils.ts +8 -6
  79. package/tsconfig.json +2 -1
  80. package/dist/chunk-GIZWJXSR.js.map +0 -1
  81. package/dist/implementation/subscriptionScope.d.ts +0 -34
  82. package/dist/implementation/subscriptionScope.d.ts.map +0 -1
  83. package/src/implementation/subscriptionScope.ts +0 -165
@@ -0,0 +1,21 @@
1
+ import type { CoValue, RefEncoded } from "../internal.js";
2
+ import { SubscriptionScope } from "./SubscriptionScope.js";
3
+ export declare function getSubscriptionScope<D extends CoValue>(value: D): SubscriptionScope<D>;
4
+ /** Autoload internals */
5
+ /**
6
+ * Given a coValue, access a child coValue by key
7
+ *
8
+ * By subscribing to a given key, the subscription will automatically react to the id changes
9
+ * on that key (e.g. deleting the key value will result on unsubscribing from the id)
10
+ */
11
+ export declare function accessChildByKey<D extends CoValue>(parent: D, childId: string, key: string): any;
12
+ /**
13
+ * Given a coValue, access a child coValue by id
14
+ *
15
+ * By subscribing to a given id, the subscription becomes permanent and will unsubscribe
16
+ * only when the root subscription scope is destroyed.
17
+ *
18
+ * Used for refs that never change (e.g. CoFeed entries, CoMap edits)
19
+ */
20
+ export declare function accessChildById<D extends CoValue>(parent: D, childId: string, schema: RefEncoded<CoValue>): any;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/subscribe/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC,wBAwB/D;AAED,yBAAyB;AAEzB;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAChD,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,OAeZ;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,OAa5B"}
@@ -0,0 +1,12 @@
1
+ import type { CoValue, RefsToResolve, Resolved } from "../internal.js";
2
+ import type { JazzError } from "./JazzError.js";
3
+ export type SubscriptionValue<D extends CoValue, R extends RefsToResolve<D>> = {
4
+ type: "loaded";
5
+ value: Resolved<D, R>;
6
+ id: string;
7
+ } | JazzError;
8
+ export type Unloaded = {
9
+ type: "unloaded";
10
+ id: string;
11
+ };
12
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/subscribe/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,IACvE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACrD,SAAS,CAAC;AACd,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { RawCoValue } from "cojson";
2
+ import { CoValue, RefEncoded } from "../internal.js";
3
+ import { SubscriptionScope } from "./SubscriptionScope.js";
4
+ export declare function getOwnerFromRawValue(raw: RawCoValue): import("../exports.js").Account | import("../exports.js").Group;
5
+ export declare function createCoValue<D extends CoValue>(ref: RefEncoded<D>, raw: RawCoValue, subscriptionScope: SubscriptionScope<D>): {
6
+ type: "loaded";
7
+ value: D;
8
+ id: import("../internal.js").ID<D>;
9
+ };
10
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/subscribe/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAY,MAAM,QAAQ,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAyB,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,mEAQnD;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAC7C,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EAClB,GAAG,EAAE,UAAU,EACf,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;EAgBxC"}
package/dist/testing.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  createAnonymousJazzContext,
6
6
  createJazzContext,
7
7
  randomSessionProvider
8
- } from "./chunk-GIZWJXSR.js";
8
+ } from "./chunk-ITSHLDQB.js";
9
9
 
10
10
  // src/testing.ts
11
11
  import { LocalNode } from "cojson";
@@ -110,7 +110,7 @@ var TestJazzContextManager = class _TestJazzContextManager extends JazzContextMa
110
110
  const node = account._raw.core.node;
111
111
  const credentials = {
112
112
  accountID: account.id,
113
- accountSecret: node.account.agentSecret,
113
+ accountSecret: node.getCurrentAgent().agentSecret,
114
114
  secretSeed: SecretSeedMap.get(account.id),
115
115
  provider
116
116
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing.ts"],"sourcesContent":["import { AgentSecret, CryptoProvider, LocalNode, Peer } from \"cojson\";\nimport { cojsonInternals } from \"cojson\";\nimport { PureJSCrypto } from \"cojson/dist/crypto/PureJSCrypto\";\nimport {\n Account,\n AccountClass,\n AuthCredentials,\n JazzContextManagerAuthProps,\n} from \"./exports.js\";\nimport {\n JazzContextManager,\n JazzContextManagerBaseProps,\n} from \"./implementation/ContextManager.js\";\nimport { activeAccountContext } from \"./implementation/activeAccountContext.js\";\nimport {\n type AnonymousJazzAgent,\n type CoValueClass,\n createAnonymousJazzContext,\n createJazzContext,\n randomSessionProvider,\n} from \"./internal.js\";\n\nconst syncServer: { current: LocalNode | null } = { current: null };\n\ntype TestAccountSchema<Acc extends Account> = CoValueClass<Acc> & {\n fromNode: (typeof Account)[\"fromNode\"];\n create: (options: {\n creationProps: { name: string };\n initialAgentSecret?: AgentSecret;\n peersToLoadFrom?: Peer[];\n crypto: CryptoProvider;\n }) => Promise<Acc>;\n};\n\nexport class TestJSCrypto extends PureJSCrypto {\n static async create() {\n if (\"navigator\" in globalThis && navigator.userAgent?.includes(\"jsdom\")) {\n // Mocking crypto seal & encrypt to make it work with JSDom. Getting \"Error: Uint8Array expected\" there\n const crypto = new PureJSCrypto();\n\n crypto.seal = (options) =>\n `sealed_U${cojsonInternals.stableStringify(options.message)}` as any;\n crypto.unseal = (sealed) =>\n JSON.parse(sealed.substring(\"sealed_U\".length));\n crypto.encrypt = (message) =>\n `encrypted_U${cojsonInternals.stableStringify(message)}` as any;\n crypto.decryptRaw = (encrypted) =>\n encrypted.substring(\"encrypted_U\".length) as any;\n\n return crypto;\n }\n\n // For non-jsdom environments, we use the real crypto\n return new PureJSCrypto();\n }\n}\n\nexport function getPeerConnectedToTestSyncServer() {\n if (!syncServer.current) {\n throw new Error(\"Sync server not initialized\");\n }\n\n const [aPeer, bPeer] = cojsonInternals.connectedPeers(\n Math.random().toString(),\n Math.random().toString(),\n {\n peer1role: \"server\",\n peer2role: \"server\",\n },\n );\n syncServer.current.syncManager.addPeer(aPeer);\n\n return bPeer;\n}\n\nconst SecretSeedMap = new Map<string, Uint8Array>();\nlet isMigrationActive = false;\n\nexport async function createJazzTestAccount<Acc extends Account>(options?: {\n isCurrentActiveAccount?: boolean;\n AccountSchema?: CoValueClass<Acc>;\n creationProps?: Record<string, unknown>;\n}): Promise<Acc> {\n const AccountSchema = (options?.AccountSchema ??\n Account) as unknown as TestAccountSchema<Acc>;\n const peers = [];\n if (syncServer.current) {\n peers.push(getPeerConnectedToTestSyncServer());\n }\n\n const crypto = await TestJSCrypto.create();\n const secretSeed = crypto.newRandomSecretSeed();\n\n const { node } = await LocalNode.withNewlyCreatedAccount({\n creationProps: {\n name: \"Test Account\",\n ...options?.creationProps,\n },\n initialAgentSecret: crypto.agentSecretFromSecretSeed(secretSeed),\n crypto,\n peersToLoadFrom: peers,\n migration: async (rawAccount, _node, creationProps) => {\n if (isMigrationActive) {\n throw new Error(\n \"It is not possible to create multiple accounts in parallel inside the test environment.\",\n );\n }\n\n isMigrationActive = true;\n\n const account = new AccountSchema({\n fromRaw: rawAccount,\n });\n\n // We need to set the account as current because the migration\n // will probably rely on the global me\n const prevActiveAccount = activeAccountContext.maybeGet();\n activeAccountContext.set(account);\n\n await account.applyMigration?.(creationProps);\n\n if (!options?.isCurrentActiveAccount) {\n activeAccountContext.set(prevActiveAccount);\n }\n\n isMigrationActive = false;\n },\n });\n\n const account = AccountSchema.fromNode(node);\n SecretSeedMap.set(account.id, secretSeed);\n\n if (options?.isCurrentActiveAccount) {\n activeAccountContext.set(account);\n }\n\n return account;\n}\n\nexport function setActiveAccount(account: Account) {\n activeAccountContext.set(account);\n}\n\nexport async function createJazzTestGuest() {\n const ctx = await createAnonymousJazzContext({\n crypto: await PureJSCrypto.create(),\n peersToLoadFrom: [],\n });\n\n return {\n guest: ctx.agent,\n };\n}\n\nexport type TestJazzContextManagerProps<Acc extends Account> =\n JazzContextManagerBaseProps<Acc> & {\n defaultProfileName?: string;\n AccountSchema?: AccountClass<Acc>;\n isAuthenticated?: boolean;\n };\n\nexport class TestJazzContextManager<\n Acc extends Account,\n> extends JazzContextManager<Acc, TestJazzContextManagerProps<Acc>> {\n static fromAccountOrGuest<Acc extends Account>(\n account?: Acc | { guest: AnonymousJazzAgent },\n props?: TestJazzContextManagerProps<Acc>,\n ) {\n if (account && \"guest\" in account) {\n return this.fromGuest<Acc>(account, props);\n }\n\n return this.fromAccount<Acc>(account ?? (Account.getMe() as Acc), props);\n }\n\n static fromAccount<Acc extends Account>(\n account: Acc,\n props?: TestJazzContextManagerProps<Acc>,\n ) {\n const context = new TestJazzContextManager<Acc>();\n\n const provider = props?.isAuthenticated ? \"testProvider\" : \"anonymous\";\n const storage = context.getAuthSecretStorage();\n const node = account._raw.core.node;\n\n const credentials = {\n accountID: account.id,\n accountSecret: node.account.agentSecret,\n secretSeed: SecretSeedMap.get(account.id),\n provider,\n } satisfies AuthCredentials;\n\n storage.set(credentials);\n\n context.updateContext(\n {\n AccountSchema: account.constructor as AccountClass<Acc>,\n ...props,\n },\n {\n me: account,\n node,\n done: () => {\n node.gracefulShutdown();\n },\n logOut: async () => {\n await storage.clear();\n node.gracefulShutdown();\n },\n },\n {\n credentials,\n },\n );\n\n return context;\n }\n\n static fromGuest<Acc extends Account>(\n { guest }: { guest: AnonymousJazzAgent },\n props: TestJazzContextManagerProps<Acc> = {},\n ) {\n const context = new TestJazzContextManager<Acc>();\n const node = guest.node;\n\n context.updateContext(props, {\n guest,\n node,\n done: () => {\n node.gracefulShutdown();\n },\n logOut: async () => {\n node.gracefulShutdown();\n },\n });\n\n return context;\n }\n\n async getNewContext(\n props: TestJazzContextManagerProps<Acc>,\n authProps?: JazzContextManagerAuthProps,\n ) {\n if (!syncServer.current) {\n throw new Error(\n \"You need to setup a test sync server with setupJazzTestSync to use the Auth functions\",\n );\n }\n\n const context = await createJazzContext<Acc>({\n credentials: authProps?.credentials,\n defaultProfileName: props.defaultProfileName,\n newAccountProps: authProps?.newAccountProps,\n peersToLoadFrom: [getPeerConnectedToTestSyncServer()],\n crypto: await TestJSCrypto.create(),\n sessionProvider: randomSessionProvider,\n authSecretStorage: this.getAuthSecretStorage(),\n AccountSchema: props.AccountSchema,\n });\n\n return {\n me: context.account,\n node: context.node,\n done: () => {\n context.done();\n },\n logOut: () => {\n return context.logOut();\n },\n };\n }\n}\n\nexport async function linkAccounts(\n a: Account,\n b: Account,\n aRole: \"server\" | \"client\" = \"server\",\n bRole: \"server\" | \"client\" = \"server\",\n) {\n const [aPeer, bPeer] = cojsonInternals.connectedPeers(b.id, a.id, {\n peer1role: aRole,\n peer2role: bRole,\n });\n\n a._raw.core.node.syncManager.addPeer(aPeer);\n b._raw.core.node.syncManager.addPeer(bPeer);\n\n await a.waitForAllCoValuesSync();\n await b.waitForAllCoValuesSync();\n}\n\nexport async function setupJazzTestSync() {\n if (syncServer.current) {\n syncServer.current.gracefulShutdown();\n }\n\n const account = await Account.create({\n creationProps: {\n name: \"Test Account\",\n },\n crypto: await TestJSCrypto.create(),\n });\n\n syncServer.current = account._raw.core.node;\n\n return account;\n}\n"],"mappings":"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","names":["account"]}
1
+ {"version":3,"sources":["../src/testing.ts"],"sourcesContent":["import { AgentSecret, CryptoProvider, LocalNode, Peer } from \"cojson\";\nimport { cojsonInternals } from \"cojson\";\nimport { PureJSCrypto } from \"cojson/dist/crypto/PureJSCrypto\";\nimport {\n Account,\n AccountClass,\n AuthCredentials,\n JazzContextManagerAuthProps,\n} from \"./exports.js\";\nimport {\n JazzContextManager,\n JazzContextManagerBaseProps,\n} from \"./implementation/ContextManager.js\";\nimport { activeAccountContext } from \"./implementation/activeAccountContext.js\";\nimport {\n type AnonymousJazzAgent,\n type CoValueClass,\n createAnonymousJazzContext,\n createJazzContext,\n randomSessionProvider,\n} from \"./internal.js\";\n\nconst syncServer: { current: LocalNode | null } = { current: null };\n\ntype TestAccountSchema<Acc extends Account> = CoValueClass<Acc> & {\n fromNode: (typeof Account)[\"fromNode\"];\n create: (options: {\n creationProps: { name: string };\n initialAgentSecret?: AgentSecret;\n peersToLoadFrom?: Peer[];\n crypto: CryptoProvider;\n }) => Promise<Acc>;\n};\n\nexport class TestJSCrypto extends PureJSCrypto {\n static async create() {\n if (\"navigator\" in globalThis && navigator.userAgent?.includes(\"jsdom\")) {\n // Mocking crypto seal & encrypt to make it work with JSDom. Getting \"Error: Uint8Array expected\" there\n const crypto = new PureJSCrypto();\n\n crypto.seal = (options) =>\n `sealed_U${cojsonInternals.stableStringify(options.message)}` as any;\n crypto.unseal = (sealed) =>\n JSON.parse(sealed.substring(\"sealed_U\".length));\n crypto.encrypt = (message) =>\n `encrypted_U${cojsonInternals.stableStringify(message)}` as any;\n crypto.decryptRaw = (encrypted) =>\n encrypted.substring(\"encrypted_U\".length) as any;\n\n return crypto;\n }\n\n // For non-jsdom environments, we use the real crypto\n return new PureJSCrypto();\n }\n}\n\nexport function getPeerConnectedToTestSyncServer() {\n if (!syncServer.current) {\n throw new Error(\"Sync server not initialized\");\n }\n\n const [aPeer, bPeer] = cojsonInternals.connectedPeers(\n Math.random().toString(),\n Math.random().toString(),\n {\n peer1role: \"server\",\n peer2role: \"server\",\n },\n );\n syncServer.current.syncManager.addPeer(aPeer);\n\n return bPeer;\n}\n\nconst SecretSeedMap = new Map<string, Uint8Array>();\nlet isMigrationActive = false;\n\nexport async function createJazzTestAccount<Acc extends Account>(options?: {\n isCurrentActiveAccount?: boolean;\n AccountSchema?: CoValueClass<Acc>;\n creationProps?: Record<string, unknown>;\n}): Promise<Acc> {\n const AccountSchema = (options?.AccountSchema ??\n Account) as unknown as TestAccountSchema<Acc>;\n const peers = [];\n if (syncServer.current) {\n peers.push(getPeerConnectedToTestSyncServer());\n }\n\n const crypto = await TestJSCrypto.create();\n const secretSeed = crypto.newRandomSecretSeed();\n\n const { node } = await LocalNode.withNewlyCreatedAccount({\n creationProps: {\n name: \"Test Account\",\n ...options?.creationProps,\n },\n initialAgentSecret: crypto.agentSecretFromSecretSeed(secretSeed),\n crypto,\n peersToLoadFrom: peers,\n migration: async (rawAccount, _node, creationProps) => {\n if (isMigrationActive) {\n throw new Error(\n \"It is not possible to create multiple accounts in parallel inside the test environment.\",\n );\n }\n\n isMigrationActive = true;\n\n const account = new AccountSchema({\n fromRaw: rawAccount,\n });\n\n // We need to set the account as current because the migration\n // will probably rely on the global me\n const prevActiveAccount = activeAccountContext.maybeGet();\n activeAccountContext.set(account);\n\n await account.applyMigration?.(creationProps);\n\n if (!options?.isCurrentActiveAccount) {\n activeAccountContext.set(prevActiveAccount);\n }\n\n isMigrationActive = false;\n },\n });\n\n const account = AccountSchema.fromNode(node);\n SecretSeedMap.set(account.id, secretSeed);\n\n if (options?.isCurrentActiveAccount) {\n activeAccountContext.set(account);\n }\n\n return account;\n}\n\nexport function setActiveAccount(account: Account) {\n activeAccountContext.set(account);\n}\n\nexport async function createJazzTestGuest() {\n const ctx = await createAnonymousJazzContext({\n crypto: await PureJSCrypto.create(),\n peersToLoadFrom: [],\n });\n\n return {\n guest: ctx.agent,\n };\n}\n\nexport type TestJazzContextManagerProps<Acc extends Account> =\n JazzContextManagerBaseProps<Acc> & {\n defaultProfileName?: string;\n AccountSchema?: AccountClass<Acc>;\n isAuthenticated?: boolean;\n };\n\nexport class TestJazzContextManager<\n Acc extends Account,\n> extends JazzContextManager<Acc, TestJazzContextManagerProps<Acc>> {\n static fromAccountOrGuest<Acc extends Account>(\n account?: Acc | { guest: AnonymousJazzAgent },\n props?: TestJazzContextManagerProps<Acc>,\n ) {\n if (account && \"guest\" in account) {\n return this.fromGuest<Acc>(account, props);\n }\n\n return this.fromAccount<Acc>(account ?? (Account.getMe() as Acc), props);\n }\n\n static fromAccount<Acc extends Account>(\n account: Acc,\n props?: TestJazzContextManagerProps<Acc>,\n ) {\n const context = new TestJazzContextManager<Acc>();\n\n const provider = props?.isAuthenticated ? \"testProvider\" : \"anonymous\";\n const storage = context.getAuthSecretStorage();\n const node = account._raw.core.node;\n\n const credentials = {\n accountID: account.id,\n accountSecret: node.getCurrentAgent().agentSecret,\n secretSeed: SecretSeedMap.get(account.id),\n provider,\n } satisfies AuthCredentials;\n\n storage.set(credentials);\n\n context.updateContext(\n {\n AccountSchema: account.constructor as AccountClass<Acc>,\n ...props,\n },\n {\n me: account,\n node,\n done: () => {\n node.gracefulShutdown();\n },\n logOut: async () => {\n await storage.clear();\n node.gracefulShutdown();\n },\n },\n {\n credentials,\n },\n );\n\n return context;\n }\n\n static fromGuest<Acc extends Account>(\n { guest }: { guest: AnonymousJazzAgent },\n props: TestJazzContextManagerProps<Acc> = {},\n ) {\n const context = new TestJazzContextManager<Acc>();\n const node = guest.node;\n\n context.updateContext(props, {\n guest,\n node,\n done: () => {\n node.gracefulShutdown();\n },\n logOut: async () => {\n node.gracefulShutdown();\n },\n });\n\n return context;\n }\n\n async getNewContext(\n props: TestJazzContextManagerProps<Acc>,\n authProps?: JazzContextManagerAuthProps,\n ) {\n if (!syncServer.current) {\n throw new Error(\n \"You need to setup a test sync server with setupJazzTestSync to use the Auth functions\",\n );\n }\n\n const context = await createJazzContext<Acc>({\n credentials: authProps?.credentials,\n defaultProfileName: props.defaultProfileName,\n newAccountProps: authProps?.newAccountProps,\n peersToLoadFrom: [getPeerConnectedToTestSyncServer()],\n crypto: await TestJSCrypto.create(),\n sessionProvider: randomSessionProvider,\n authSecretStorage: this.getAuthSecretStorage(),\n AccountSchema: props.AccountSchema,\n });\n\n return {\n me: context.account,\n node: context.node,\n done: () => {\n context.done();\n },\n logOut: () => {\n return context.logOut();\n },\n };\n }\n}\n\nexport async function linkAccounts(\n a: Account,\n b: Account,\n aRole: \"server\" | \"client\" = \"server\",\n bRole: \"server\" | \"client\" = \"server\",\n) {\n const [aPeer, bPeer] = cojsonInternals.connectedPeers(b.id, a.id, {\n peer1role: aRole,\n peer2role: bRole,\n });\n\n a._raw.core.node.syncManager.addPeer(aPeer);\n b._raw.core.node.syncManager.addPeer(bPeer);\n\n await a.waitForAllCoValuesSync();\n await b.waitForAllCoValuesSync();\n}\n\nexport async function setupJazzTestSync() {\n if (syncServer.current) {\n syncServer.current.gracefulShutdown();\n }\n\n const account = await Account.create({\n creationProps: {\n name: \"Test Account\",\n },\n crypto: await TestJSCrypto.create(),\n });\n\n syncServer.current = account._raw.core.node;\n\n return account;\n}\n"],"mappings":"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","names":["account"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=coMap.record.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coMap.record.test.d.ts","sourceRoot":"","sources":["../../src/tests/coMap.record.test.ts"],"names":[],"mappings":""}
@@ -4,7 +4,7 @@ export declare function setupAccount(): Promise<{
4
4
  me: Account & {
5
5
  isLocalNodeOwner: true;
6
6
  sessionID: import("cojson").SessionID;
7
- _raw: import("cojson").RawControlledAccount;
7
+ _raw: import("cojson").RawAccount;
8
8
  };
9
9
  meOnSecondPeer: Account;
10
10
  }>;
@@ -16,6 +16,6 @@ export declare function setupTwoNodes(options?: {
16
16
  clientAccount: Account;
17
17
  serverAccount: Account;
18
18
  }>;
19
- export declare function waitFor(callback: () => boolean | void): Promise<void>;
19
+ export declare function waitFor(callback: () => boolean | void | Promise<boolean | void>): Promise<void>;
20
20
  export declare function loadCoValueOrFail<V extends RawCoValue>(node: LocalNode, id: CoID<V>): Promise<V>;
21
21
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tests/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGrD,OAAO,EACL,OAAO,EAGR,MAAM,UAAU,CAAC;AAIlB,wBAAsB,YAAY;;;;;;;GA+BjC;AAED,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,mBAAmB,CAAC,EAAE,OAAO,OAAO,CAAC;CACtC;;;;;GAgDA;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,GAAG,IAAI,iBA0BrD;AAED,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,UAAU,EAC1D,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,GACV,OAAO,CAAC,CAAC,CAAC,CAMZ"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tests/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGrD,OAAO,EACL,OAAO,EAGR,MAAM,UAAU,CAAC;AAIlB,wBAAsB,YAAY;;;;;;;GA+BjC;AAED,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,mBAAmB,CAAC,EAAE,OAAO,OAAO,CAAC;CACtC;;;;;GAgDA;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,iBA2BzD;AAED,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,UAAU,EAC1D,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,GACV,OAAO,CAAC,CAAC,CAAC,CAMZ"}
package/package.json CHANGED
@@ -17,11 +17,11 @@
17
17
  },
18
18
  "type": "module",
19
19
  "license": "MIT",
20
- "version": "0.13.16",
20
+ "version": "0.13.18",
21
21
  "dependencies": {
22
22
  "@scure/bip39": "^1.3.0",
23
23
  "fast-myers-diff": "^3.2.0",
24
- "cojson": "0.13.16"
24
+ "cojson": "0.13.18"
25
25
  },
26
26
  "devDependencies": {
27
27
  "tsup": "8.3.5",
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  AgentSecret,
3
3
  CoID,
4
+ ControlledAccount,
4
5
  CryptoProvider,
5
6
  Everyone,
6
7
  InviteSecret,
@@ -9,7 +10,6 @@ import {
9
10
  RawAccount,
10
11
  RawCoMap,
11
12
  RawCoValue,
12
- RawControlledAccount,
13
13
  Role,
14
14
  SessionID,
15
15
  cojsonInternals,
@@ -31,6 +31,7 @@ import {
31
31
  SchemaInit,
32
32
  SubscribeListenerOptions,
33
33
  SubscribeRestArgs,
34
+ accessChildByKey,
34
35
  ensureCoValueLoaded,
35
36
  inspect,
36
37
  loadCoValue,
@@ -38,7 +39,6 @@ import {
38
39
  parseSubscribeRestArgs,
39
40
  subscribeToCoValueWithoutMe,
40
41
  subscribeToExistingCoValue,
41
- subscriptionsScopes,
42
42
  } from "../internal.js";
43
43
  import { coValuesCache } from "../lib/cache.js";
44
44
  import { RegisteredAccount } from "../types.js";
@@ -57,7 +57,7 @@ export type AccountCreationProps = {
57
57
  export class Account extends CoValueBase implements CoValue {
58
58
  declare id: ID<this>;
59
59
  declare _type: "Account";
60
- declare _raw: RawAccount | RawControlledAccount;
60
+ declare _raw: RawAccount;
61
61
 
62
62
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
63
  static _schema: any;
@@ -86,10 +86,12 @@ export class Account extends CoValueBase implements CoValue {
86
86
  get _loadedAs(): Account | AnonymousJazzAgent {
87
87
  if (this.isLocalNodeOwner) return this;
88
88
 
89
- const rawAccount = this._raw.core.node.account;
89
+ const agent = this._raw.core.node.getCurrentAgent();
90
90
 
91
- if (rawAccount instanceof RawAccount) {
92
- return coValuesCache.get(rawAccount, () => Account.fromRaw(rawAccount));
91
+ if (agent instanceof ControlledAccount) {
92
+ return coValuesCache.get(agent.account, () =>
93
+ Account.fromRaw(agent.account),
94
+ );
93
95
  }
94
96
 
95
97
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -98,6 +100,16 @@ export class Account extends CoValueBase implements CoValue {
98
100
  declare profile: Profile | null;
99
101
  declare root: CoMap | null;
100
102
 
103
+ getDescriptor(key: string) {
104
+ if (key === "profile") {
105
+ return this._schema.profile;
106
+ } else if (key === "root") {
107
+ return this._schema.root;
108
+ }
109
+
110
+ return undefined;
111
+ }
112
+
101
113
  get _refs(): {
102
114
  profile: RefIfCoValue<Profile> | undefined;
103
115
  root: RefIfCoValue<CoMap> | undefined;
@@ -118,6 +130,7 @@ export class Account extends CoValueBase implements CoValue {
118
130
  this._schema.profile as RefEncoded<
119
131
  NonNullable<this["profile"]> & CoValue
120
132
  >,
133
+ this,
121
134
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
135
  ) as any as RefIfCoValue<this["profile"]>),
123
136
  root:
@@ -126,6 +139,7 @@ export class Account extends CoValueBase implements CoValue {
126
139
  rootID,
127
140
  this._loadedAs,
128
141
  this._schema.root as RefEncoded<NonNullable<this["root"]> & CoValue>,
142
+ this,
129
143
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
144
  ) as any as RefIfCoValue<this["root"]>),
131
145
  };
@@ -144,13 +158,13 @@ export class Account extends CoValueBase implements CoValue {
144
158
  isLocalNodeOwner: boolean;
145
159
  sessionID: SessionID | undefined;
146
160
 
147
- constructor(options: { fromRaw: RawAccount | RawControlledAccount }) {
161
+ constructor(options: { fromRaw: RawAccount }) {
148
162
  super();
149
163
  if (!("fromRaw" in options)) {
150
164
  throw new Error("Can only construct account from raw or with .create()");
151
165
  }
152
166
  this.isLocalNodeOwner =
153
- options.fromRaw.id == options.fromRaw.core.node.account.id;
167
+ options.fromRaw.id == options.fromRaw.core.node.getCurrentAgent().id;
154
168
 
155
169
  Object.defineProperties(this, {
156
170
  id: {
@@ -196,10 +210,15 @@ export class Account extends CoValueBase implements CoValue {
196
210
  ref: Ref<RegisteredAccount> | undefined;
197
211
  account: RegisteredAccount | null | undefined;
198
212
  }> {
199
- const ref = new Ref<RegisteredAccount>(this.id, this._loadedAs, {
200
- ref: () => this.constructor as typeof Account,
201
- optional: false,
202
- });
213
+ const ref = new Ref<RegisteredAccount>(
214
+ this.id,
215
+ this._loadedAs,
216
+ {
217
+ ref: () => this.constructor as typeof Account,
218
+ optional: false,
219
+ },
220
+ this,
221
+ );
203
222
 
204
223
  return [{ id: this.id, role: "admin", ref, account: this }];
205
224
  }
@@ -234,7 +253,7 @@ export class Account extends CoValueBase implements CoValue {
234
253
  throw new Error("Only a controlled account can accept invites");
235
254
  }
236
255
 
237
- await (this._raw as RawControlledAccount).acceptInvite(
256
+ await this._raw.core.node.acceptInvite(
238
257
  valueID as unknown as CoID<RawCoValue>,
239
258
  inviteSecret,
240
259
  );
@@ -304,7 +323,7 @@ export class Account extends CoValueBase implements CoValue {
304
323
  node: LocalNode,
305
324
  ): A {
306
325
  return new this({
307
- fromRaw: node.account as RawControlledAccount,
326
+ fromRaw: node.expectCurrentAccount("jazz-tools/Account.fromNode"),
308
327
  }) as A;
309
328
  }
310
329
 
@@ -440,16 +459,14 @@ export class Account extends CoValueBase implements CoValue {
440
459
 
441
460
  export const AccountAndGroupProxyHandler: ProxyHandler<Account | Group> = {
442
461
  get(target, key, receiver) {
443
- if (key === "profile") {
444
- const ref = target._refs.profile;
445
- return ref
446
- ? ref.accessFrom(receiver, "profile")
447
- : // eslint-disable-next-line @typescript-eslint/no-explicit-any
448
- (undefined as any);
449
- } else if (key === "root") {
450
- const ref = target._refs.root;
451
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
452
- return ref ? ref.accessFrom(receiver, "root") : (undefined as any);
462
+ if (key === "profile" || key === "root") {
463
+ const id = target._raw.get(key);
464
+
465
+ if (id) {
466
+ return accessChildByKey(target, id, key);
467
+ } else {
468
+ return undefined;
469
+ }
453
470
  } else {
454
471
  return Reflect.get(target, key, receiver);
455
472
  }
@@ -471,17 +488,12 @@ export const AccountAndGroupProxyHandler: ProxyHandler<Account | Group> = {
471
488
  "trusting",
472
489
  );
473
490
  }
474
- subscriptionsScopes
475
- .get(receiver)
476
- ?.onRefAccessedOrSet(target.id, value.id);
491
+
477
492
  return true;
478
493
  } else if (key === "root") {
479
494
  if (value) {
480
495
  target._raw.set("root", value.id as unknown as CoID<RawCoMap>);
481
496
  }
482
- subscriptionsScopes
483
- .get(receiver)
484
- ?.onRefAccessedOrSet(target.id, value.id);
485
497
  return true;
486
498
  } else {
487
499
  return Reflect.set(target, key, value, receiver);
@@ -507,7 +519,7 @@ export const AccountAndGroupProxyHandler: ProxyHandler<Account | Group> = {
507
519
  export function isControlledAccount(account: Account): account is Account & {
508
520
  isLocalNodeOwner: true;
509
521
  sessionID: SessionID;
510
- _raw: RawControlledAccount;
522
+ _raw: RawAccount;
511
523
  } {
512
524
  return account.isLocalNodeOwner;
513
525
  }
@@ -30,6 +30,7 @@ import {
30
30
  ItemsSym,
31
31
  Ref,
32
32
  SchemaInit,
33
+ accessChildById,
33
34
  co,
34
35
  ensureCoValueLoaded,
35
36
  inspect,
@@ -230,6 +231,10 @@ export class CoFeed<Item = any> extends CoValueBase implements CoValue {
230
231
  return instance;
231
232
  }
232
233
 
234
+ getItemsDescriptor() {
235
+ return this._schema?.[ItemsSym];
236
+ }
237
+
233
238
  /**
234
239
  * Push items to this `CoFeed`
235
240
  *
@@ -438,9 +443,10 @@ function entryFromRawEntry<Item>(
438
443
  } else if ("encoded" in itemField) {
439
444
  return itemField.encoded.decode(rawEntry.value);
440
445
  } else if (isRefEncoded(itemField)) {
441
- return this.ref?.accessFrom(
446
+ return accessChildById(
442
447
  accessFrom,
443
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".value",
448
+ rawEntry.value as string,
449
+ itemField,
444
450
  ) as NonNullable<Item> extends CoValue ? (CoValue & Item) | null : Item;
445
451
  } else {
446
452
  throw new Error("Invalid item field schema");
@@ -455,6 +461,7 @@ function entryFromRawEntry<Item>(
455
461
  rawId as unknown as ID<CoValue>,
456
462
  loadedAs,
457
463
  itemField,
464
+ accessFrom,
458
465
  ) as NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never;
459
466
  } else {
460
467
  return undefined as never;
@@ -463,13 +470,10 @@ function entryFromRawEntry<Item>(
463
470
  get by() {
464
471
  return (
465
472
  accountID &&
466
- new Ref<Account>(accountID as unknown as ID<Account>, loadedAs, {
473
+ accessChildById(accessFrom, accountID, {
467
474
  ref: RegisteredSchemas["Account"],
468
475
  optional: false,
469
- })?.accessFrom(
470
- accessFrom,
471
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".by",
472
- )
476
+ })
473
477
  );
474
478
  },
475
479
  madeAt: rawEntry.at,
@@ -906,13 +910,24 @@ export class FileStream extends CoValueBase implements CoValue {
906
910
  * Subscribe to a `FileStream`, when you have an ID but don't have a `FileStream` instance yet
907
911
  * @category Subscription & Loading
908
912
  */
909
- static subscribe<C extends FileStream>(
910
- this: CoValueClass<C>,
911
- id: ID<C>,
912
- options: { loadAs?: Account | AnonymousJazzAgent },
913
- listener: (value: Resolved<C, true>) => void,
913
+ static subscribe<F extends FileStream, const R extends RefsToResolve<F>>(
914
+ this: CoValueClass<F>,
915
+ id: ID<F>,
916
+ listener: (value: Resolved<F, R>, unsubscribe: () => void) => void,
917
+ ): () => void;
918
+ static subscribe<F extends FileStream, const R extends RefsToResolve<F>>(
919
+ this: CoValueClass<F>,
920
+ id: ID<F>,
921
+ options: SubscribeListenerOptions<F, R>,
922
+ listener: (value: Resolved<F, R>, unsubscribe: () => void) => void,
923
+ ): () => void;
924
+ static subscribe<F extends FileStream, const R extends RefsToResolve<F>>(
925
+ this: CoValueClass<F>,
926
+ id: ID<F>,
927
+ ...args: SubscribeRestArgs<F, R>
914
928
  ): () => void {
915
- return subscribeToCoValueWithoutMe<C, true>(this, id, options, listener);
929
+ const { options, listener } = parseSubscribeRestArgs(args);
930
+ return subscribeToCoValueWithoutMe<F, R>(this, id, options, listener);
916
931
  }
917
932
 
918
933
  /**
@@ -1,5 +1,5 @@
1
1
  import type { JsonValue, RawCoList } from "cojson";
2
- import { RawAccount } from "cojson";
2
+ import { ControlledAccount, RawAccount } from "cojson";
3
3
  import { calcPatch } from "fast-myers-diff";
4
4
  import type {
5
5
  CoValue,
@@ -21,6 +21,7 @@ import {
21
21
  ItemsSym,
22
22
  Ref,
23
23
  SchemaInit,
24
+ accessChildByKey,
24
25
  co,
25
26
  ensureCoValueLoaded,
26
27
  inspect,
@@ -31,7 +32,6 @@ import {
31
32
  parseSubscribeRestArgs,
32
33
  subscribeToCoValueWithoutMe,
33
34
  subscribeToExistingCoValue,
34
- subscriptionsScopes,
35
35
  } from "../internal.js";
36
36
  import { coValuesCache } from "../lib/cache.js";
37
37
  import { RegisteredAccount } from "../types.js";
@@ -147,6 +147,7 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
147
147
  >;
148
148
  } {
149
149
  return makeRefs<number>(
150
+ this,
150
151
  (idx) => this._raw.get(idx) as unknown as ID<CoValue>,
151
152
  () => Array.from({ length: this._raw.entries().length }, (_, idx) => idx),
152
153
  this._loadedAs,
@@ -167,11 +168,11 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
167
168
  }
168
169
 
169
170
  get _loadedAs() {
170
- const rawAccount = this._raw.core.node.account;
171
+ const agent = this._raw.core.node.getCurrentAgent();
171
172
 
172
- if (rawAccount instanceof RawAccount) {
173
- return coValuesCache.get(rawAccount, () =>
174
- RegisteredSchemas["Account"].fromRaw(rawAccount),
173
+ if (agent instanceof ControlledAccount) {
174
+ return coValuesCache.get(agent.account, () =>
175
+ RegisteredSchemas["Account"].fromRaw(agent.account),
175
176
  );
176
177
  }
177
178
 
@@ -182,6 +183,10 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
182
183
  return Array;
183
184
  }
184
185
 
186
+ getItemsDescriptor() {
187
+ return this._schema?.[ItemsSym];
188
+ }
189
+
185
190
  constructor(options: { fromRaw: RawCoList } | undefined) {
186
191
  super();
187
192
 
@@ -526,12 +531,7 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
526
531
  castAs<Cl extends CoValueClass & CoValueFromRaw<CoValue>>(
527
532
  cl: Cl,
528
533
  ): InstanceType<Cl> {
529
- const casted = cl.fromRaw(this._raw) as InstanceType<Cl>;
530
- const subscriptionScope = subscriptionsScopes.get(this);
531
- if (subscriptionScope) {
532
- subscriptionsScopes.set(casted, subscriptionScope);
533
- }
534
- return casted;
534
+ return cl.fromRaw(this._raw) as InstanceType<Cl>;
535
535
  }
536
536
 
537
537
  /**
@@ -582,11 +582,7 @@ const CoListProxyHandler: ProxyHandler<CoList> = {
582
582
  } else if (isRefEncoded(itemDescriptor)) {
583
583
  return rawValue === undefined
584
584
  ? undefined
585
- : new Ref(
586
- rawValue as unknown as ID<CoValue>,
587
- target._loadedAs,
588
- itemDescriptor,
589
- ).accessFrom(receiver, Number(key));
585
+ : accessChildByKey(target, rawValue as string, key);
590
586
  }
591
587
  } else if (key === "length") {
592
588
  return target._raw.entries().length;