jazz-tools 0.8.44 → 0.8.48

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. package/.turbo/turbo-build.log +16 -10
  2. package/CHANGELOG.md +21 -0
  3. package/dist/chunk-6OHBW32Q.js +2853 -0
  4. package/dist/chunk-6OHBW32Q.js.map +1 -0
  5. package/dist/index.native.js +63 -0
  6. package/dist/index.native.js.map +1 -0
  7. package/dist/index.web.js +61 -0
  8. package/dist/index.web.js.map +1 -0
  9. package/package.json +9 -12
  10. package/src/coValues/account.ts +29 -10
  11. package/src/coValues/coFeed.ts +4 -3
  12. package/src/coValues/coList.ts +8 -5
  13. package/src/coValues/coMap.ts +14 -5
  14. package/src/coValues/deepLoading.ts +6 -12
  15. package/src/coValues/extensions/imageDef.ts +3 -1
  16. package/src/coValues/group.ts +8 -11
  17. package/src/coValues/inbox.ts +377 -0
  18. package/src/coValues/interfaces.ts +9 -6
  19. package/src/coValues/profile.ts +11 -0
  20. package/src/coValues/registeredSchemas.ts +12 -0
  21. package/src/exports.ts +21 -15
  22. package/src/implementation/anonymousJazzAgent.ts +6 -0
  23. package/src/implementation/createContext.ts +8 -9
  24. package/src/implementation/refs.ts +1 -1
  25. package/src/implementation/subscriptionScope.ts +1 -1
  26. package/src/index.native.ts +0 -1
  27. package/src/internal.ts +1 -9
  28. package/src/tests/account.test.ts +2 -2
  29. package/src/tests/coFeed.test.ts +0 -9
  30. package/src/tests/coMap.test.ts +11 -8
  31. package/src/tests/groupsAndAccounts.test.ts +1 -63
  32. package/src/tests/inbox.test.ts +299 -0
  33. package/src/tests/schemaUnion.test.ts +1 -1
  34. package/src/tests/utils.ts +14 -0
  35. package/tsup.config.ts +13 -0
  36. package/dist/native/coValues/account.js +0 -221
  37. package/dist/native/coValues/account.js.map +0 -1
  38. package/dist/native/coValues/coFeed.js +0 -571
  39. package/dist/native/coValues/coFeed.js.map +0 -1
  40. package/dist/native/coValues/coList.js +0 -404
  41. package/dist/native/coValues/coList.js.map +0 -1
  42. package/dist/native/coValues/coMap.js +0 -537
  43. package/dist/native/coValues/coMap.js.map +0 -1
  44. package/dist/native/coValues/deepLoading.js +0 -63
  45. package/dist/native/coValues/deepLoading.js.map +0 -1
  46. package/dist/native/coValues/extensions/imageDef.js +0 -42
  47. package/dist/native/coValues/extensions/imageDef.js.map +0 -1
  48. package/dist/native/coValues/group.js +0 -136
  49. package/dist/native/coValues/group.js.map +0 -1
  50. package/dist/native/coValues/interfaces.js +0 -135
  51. package/dist/native/coValues/interfaces.js.map +0 -1
  52. package/dist/native/coValues/schemaUnion.js +0 -89
  53. package/dist/native/coValues/schemaUnion.js.map +0 -1
  54. package/dist/native/exports.js +0 -5
  55. package/dist/native/exports.js.map +0 -1
  56. package/dist/native/implementation/createContext.js +0 -157
  57. package/dist/native/implementation/createContext.js.map +0 -1
  58. package/dist/native/implementation/devtoolsFormatters.js +0 -95
  59. package/dist/native/implementation/devtoolsFormatters.js.map +0 -1
  60. package/dist/native/implementation/errors.js +0 -2
  61. package/dist/native/implementation/errors.js.map +0 -1
  62. package/dist/native/implementation/inspect.js +0 -2
  63. package/dist/native/implementation/inspect.js.map +0 -1
  64. package/dist/native/implementation/refs.js +0 -115
  65. package/dist/native/implementation/refs.js.map +0 -1
  66. package/dist/native/implementation/schema.js +0 -96
  67. package/dist/native/implementation/schema.js.map +0 -1
  68. package/dist/native/implementation/subscriptionScope.js +0 -91
  69. package/dist/native/implementation/subscriptionScope.js.map +0 -1
  70. package/dist/native/implementation/symbols.js +0 -4
  71. package/dist/native/implementation/symbols.js.map +0 -1
  72. package/dist/native/index.native.js +0 -3
  73. package/dist/native/index.native.js.map +0 -1
  74. package/dist/native/internal.js +0 -18
  75. package/dist/native/internal.js.map +0 -1
  76. package/dist/native/lib/cache.js +0 -13
  77. package/dist/native/lib/cache.js.map +0 -1
  78. package/dist/native/lib/cache.test.js +0 -52
  79. package/dist/native/lib/cache.test.js.map +0 -1
  80. package/dist/web/coValues/account.js +0 -221
  81. package/dist/web/coValues/account.js.map +0 -1
  82. package/dist/web/coValues/coFeed.js +0 -571
  83. package/dist/web/coValues/coFeed.js.map +0 -1
  84. package/dist/web/coValues/coList.js +0 -404
  85. package/dist/web/coValues/coList.js.map +0 -1
  86. package/dist/web/coValues/coMap.js +0 -537
  87. package/dist/web/coValues/coMap.js.map +0 -1
  88. package/dist/web/coValues/deepLoading.js +0 -63
  89. package/dist/web/coValues/deepLoading.js.map +0 -1
  90. package/dist/web/coValues/extensions/imageDef.js +0 -42
  91. package/dist/web/coValues/extensions/imageDef.js.map +0 -1
  92. package/dist/web/coValues/group.js +0 -136
  93. package/dist/web/coValues/group.js.map +0 -1
  94. package/dist/web/coValues/interfaces.js +0 -135
  95. package/dist/web/coValues/interfaces.js.map +0 -1
  96. package/dist/web/coValues/schemaUnion.js +0 -89
  97. package/dist/web/coValues/schemaUnion.js.map +0 -1
  98. package/dist/web/exports.js +0 -5
  99. package/dist/web/exports.js.map +0 -1
  100. package/dist/web/implementation/createContext.js +0 -157
  101. package/dist/web/implementation/createContext.js.map +0 -1
  102. package/dist/web/implementation/devtoolsFormatters.js +0 -95
  103. package/dist/web/implementation/devtoolsFormatters.js.map +0 -1
  104. package/dist/web/implementation/errors.js +0 -2
  105. package/dist/web/implementation/errors.js.map +0 -1
  106. package/dist/web/implementation/inspect.js +0 -2
  107. package/dist/web/implementation/inspect.js.map +0 -1
  108. package/dist/web/implementation/refs.js +0 -115
  109. package/dist/web/implementation/refs.js.map +0 -1
  110. package/dist/web/implementation/schema.js +0 -96
  111. package/dist/web/implementation/schema.js.map +0 -1
  112. package/dist/web/implementation/subscriptionScope.js +0 -91
  113. package/dist/web/implementation/subscriptionScope.js.map +0 -1
  114. package/dist/web/implementation/symbols.js +0 -4
  115. package/dist/web/implementation/symbols.js.map +0 -1
  116. package/dist/web/index.web.js +0 -3
  117. package/dist/web/index.web.js.map +0 -1
  118. package/dist/web/internal.js +0 -18
  119. package/dist/web/internal.js.map +0 -1
  120. package/dist/web/lib/cache.js +0 -13
  121. package/dist/web/lib/cache.js.map +0 -1
  122. package/dist/web/lib/cache.test.js +0 -52
  123. package/dist/web/lib/cache.test.js.map +0 -1
@@ -0,0 +1,377 @@
1
+ import {
2
+ CoID,
3
+ InviteSecret,
4
+ RawAccount,
5
+ RawCoMap,
6
+ RawControlledAccount,
7
+ SessionID,
8
+ } from "cojson";
9
+ import { CoStreamItem, RawCoStream } from "cojson";
10
+ import { type Account } from "./account.js";
11
+ import { CoValue, CoValueClass, ID, loadCoValue } from "./interfaces.js";
12
+
13
+ export type InboxInvite = `${CoID<MessagesStream>}/${InviteSecret}`;
14
+ type TxKey = `${SessionID}/${number}`;
15
+
16
+ type MessagesStream = RawCoStream<CoID<InboxMessage<CoValue, any>>>;
17
+ type FailedMessagesStream = RawCoStream<{
18
+ errors: string[];
19
+ value: CoID<InboxMessage<CoValue, any>>;
20
+ }>;
21
+ type TxKeyStream = RawCoStream<TxKey>;
22
+ export type InboxRoot = RawCoMap<{
23
+ messages: CoID<MessagesStream>;
24
+ processed: CoID<TxKeyStream>;
25
+ failed: CoID<FailedMessagesStream>;
26
+ inviteLink: InboxInvite;
27
+ }>;
28
+
29
+ export function createInboxRoot(account: Account) {
30
+ if (!account.isMe) {
31
+ throw new Error("Account is not controlled");
32
+ }
33
+
34
+ const rawAccount = account._raw as RawControlledAccount;
35
+
36
+ const group = rawAccount.createGroup();
37
+ const messagesFeed = group.createStream<MessagesStream>();
38
+
39
+ const inboxRoot = rawAccount.createMap<InboxRoot>();
40
+ const processedFeed = rawAccount.createStream<TxKeyStream>();
41
+ const failedFeed = rawAccount.createStream<FailedMessagesStream>();
42
+
43
+ const inviteLink =
44
+ `${messagesFeed.id}/${group.createInvite("writeOnly")}` as const;
45
+
46
+ inboxRoot.set("messages", messagesFeed.id);
47
+ inboxRoot.set("processed", processedFeed.id);
48
+ inboxRoot.set("failed", failedFeed.id);
49
+
50
+ return {
51
+ id: inboxRoot.id,
52
+ inviteLink,
53
+ };
54
+ }
55
+
56
+ type InboxMessage<I extends CoValue, O extends CoValue | undefined> = RawCoMap<{
57
+ payload: ID<I>;
58
+ result: ID<O> | undefined;
59
+ processed: boolean;
60
+ error: string | undefined;
61
+ }>;
62
+
63
+ function createInboxMessage<I extends CoValue, O extends CoValue | undefined>(
64
+ payload: I,
65
+ inboxOwner: RawAccount,
66
+ ) {
67
+ const group = payload._raw.group;
68
+
69
+ if (group instanceof RawAccount) {
70
+ throw new Error("Inbox messages should be owned by a group");
71
+ }
72
+
73
+ group.addMember(inboxOwner, "writer");
74
+
75
+ const message = group.createMap<InboxMessage<I, O>>({
76
+ payload: payload.id,
77
+ result: undefined,
78
+ processed: false,
79
+ error: undefined,
80
+ });
81
+
82
+ return message;
83
+ }
84
+
85
+ export class Inbox {
86
+ account: Account;
87
+ messages: MessagesStream;
88
+ processed: TxKeyStream;
89
+ failed: FailedMessagesStream;
90
+ root: InboxRoot;
91
+ processing = new Set<`${SessionID}/${number}`>();
92
+
93
+ private constructor(
94
+ account: Account,
95
+ root: InboxRoot,
96
+ messages: MessagesStream,
97
+ processed: TxKeyStream,
98
+ failed: FailedMessagesStream,
99
+ ) {
100
+ this.account = account;
101
+ this.root = root;
102
+ this.messages = messages;
103
+ this.processed = processed;
104
+ this.failed = failed;
105
+ }
106
+
107
+ subscribe<I extends CoValue, O extends CoValue | undefined>(
108
+ Schema: CoValueClass<I>,
109
+ callback: (
110
+ message: I,
111
+ senderAccountID: ID<Account>,
112
+ ) => Promise<O | undefined | void>,
113
+ options: { retries?: number } = {},
114
+ ) {
115
+ const processed = new Set<`${SessionID}/${number}`>();
116
+ const failed = new Map<`${SessionID}/${number}`, string[]>();
117
+ const node = this.account._raw.core.node;
118
+
119
+ this.processed.subscribe((stream) => {
120
+ for (const items of Object.values(stream.items)) {
121
+ for (const item of items) {
122
+ processed.add(item.value as TxKey);
123
+ }
124
+ }
125
+ });
126
+
127
+ const { account } = this;
128
+ const { retries = 3 } = options;
129
+
130
+ let failTimer: ReturnType<typeof setTimeout> | number | undefined =
131
+ undefined;
132
+
133
+ const clearFailTimer = () => {
134
+ clearTimeout(failTimer);
135
+ failTimer = undefined;
136
+ };
137
+
138
+ const handleNewMessages = (stream: MessagesStream) => {
139
+ clearFailTimer(); // Stop the failure timers, we're going to process the failed entries anyway
140
+
141
+ for (const [sessionID, items] of Object.entries(stream.items) as [
142
+ SessionID,
143
+ CoStreamItem<CoID<InboxMessage<I, O>>>[],
144
+ ][]) {
145
+ const accountID = getAccountIDfromSessionID(sessionID);
146
+
147
+ if (!accountID) {
148
+ console.warn("Received message from unknown account", sessionID);
149
+ continue;
150
+ }
151
+
152
+ for (const item of items) {
153
+ const txKey = `${sessionID}/${item.tx.txIndex}` as const;
154
+
155
+ if (!processed.has(txKey) && !this.processing.has(txKey)) {
156
+ this.processing.add(txKey);
157
+
158
+ const id = item.value;
159
+
160
+ node
161
+ .load(id)
162
+ .then((message) => {
163
+ if (message === "unavailable") {
164
+ return Promise.reject(
165
+ new Error("Unable to load inbox message " + id),
166
+ );
167
+ }
168
+
169
+ return loadCoValue(
170
+ Schema,
171
+ message.get("payload") as ID<I>,
172
+ account,
173
+ [],
174
+ );
175
+ })
176
+ .then((value) => {
177
+ if (!value) {
178
+ return Promise.reject(
179
+ new Error("Unable to load inbox message " + id),
180
+ );
181
+ }
182
+
183
+ return callback(value, accountID);
184
+ })
185
+ .then((result) => {
186
+ const inboxMessage = node
187
+ .expectCoValueLoaded(item.value)
188
+ .getCurrentContent() as RawCoMap;
189
+
190
+ if (result) {
191
+ inboxMessage.set("result", result.id);
192
+ }
193
+
194
+ inboxMessage.set("processed", true);
195
+
196
+ this.processed.push(txKey);
197
+ this.processing.delete(txKey);
198
+ })
199
+ .catch((error) => {
200
+ console.error("Error processing inbox message", error);
201
+ this.processing.delete(txKey);
202
+ const errors = failed.get(txKey) ?? [];
203
+
204
+ const stringifiedError = String(error);
205
+ errors.push(stringifiedError);
206
+
207
+ const inboxMessage = node
208
+ .expectCoValueLoaded(item.value)
209
+ .getCurrentContent() as RawCoMap;
210
+
211
+ inboxMessage.set("error", stringifiedError);
212
+
213
+ if (errors.length > retries) {
214
+ inboxMessage.set("processed", true);
215
+ this.processed.push(txKey);
216
+ this.failed.push({ errors, value: item.value });
217
+ } else {
218
+ failed.set(txKey, errors);
219
+ if (!failTimer) {
220
+ failTimer = setTimeout(
221
+ () => handleNewMessages(stream),
222
+ 100,
223
+ );
224
+ }
225
+ }
226
+ });
227
+ }
228
+ }
229
+ }
230
+ };
231
+
232
+ return this.messages.subscribe(handleNewMessages);
233
+ }
234
+
235
+ static async load(account: Account) {
236
+ const profile = account.profile;
237
+
238
+ if (!profile) {
239
+ throw new Error("Account profile should already be loaded");
240
+ }
241
+
242
+ if (!profile.inbox) {
243
+ throw new Error("The account has not set up their inbox");
244
+ }
245
+
246
+ const node = account._raw.core.node;
247
+
248
+ const root = await node.load(profile.inbox as CoID<InboxRoot>);
249
+
250
+ if (root === "unavailable") {
251
+ throw new Error("Inbox not found");
252
+ }
253
+
254
+ const [messages, processed, failed] = await Promise.all([
255
+ node.load(root.get("messages")!),
256
+ node.load(root.get("processed")!),
257
+ node.load(root.get("failed")!),
258
+ ]);
259
+
260
+ if (
261
+ messages === "unavailable" ||
262
+ processed === "unavailable" ||
263
+ failed === "unavailable"
264
+ ) {
265
+ throw new Error("Inbox not found");
266
+ }
267
+
268
+ return new Inbox(account, root, messages, processed, failed);
269
+ }
270
+ }
271
+
272
+ export class InboxSender<I extends CoValue, O extends CoValue | undefined> {
273
+ currentAccount: Account;
274
+ owner: RawAccount;
275
+ messages: MessagesStream;
276
+
277
+ private constructor(
278
+ currentAccount: Account,
279
+ owner: RawAccount,
280
+ messages: MessagesStream,
281
+ ) {
282
+ this.currentAccount = currentAccount;
283
+ this.owner = owner;
284
+ this.messages = messages;
285
+ }
286
+
287
+ getOwnerAccount() {
288
+ return this.owner;
289
+ }
290
+
291
+ sendMessage(message: I): Promise<O extends CoValue ? ID<O> : undefined> {
292
+ const inboxMessage = createInboxMessage<I, O>(message, this.owner);
293
+
294
+ this.messages.push(inboxMessage.id);
295
+
296
+ return new Promise((resolve, reject) => {
297
+ inboxMessage.subscribe((message) => {
298
+ if (message.get("processed")) {
299
+ const error = message.get("error");
300
+ if (error) {
301
+ reject(new Error(error));
302
+ } else {
303
+ resolve(
304
+ message.get("result") as O extends CoValue ? ID<O> : undefined,
305
+ );
306
+ }
307
+ }
308
+ });
309
+ });
310
+ }
311
+
312
+ static async load<
313
+ I extends CoValue,
314
+ O extends CoValue | undefined = undefined,
315
+ >(inboxOwnerID: ID<Account>, currentAccount: Account) {
316
+ const node = currentAccount._raw.core.node;
317
+
318
+ const inboxOwnerRaw = await node.load(
319
+ inboxOwnerID as unknown as CoID<RawAccount>,
320
+ );
321
+
322
+ if (inboxOwnerRaw === "unavailable") {
323
+ throw new Error("Failed to load the inbox owner");
324
+ }
325
+
326
+ const inboxOwnerProfileRaw = await node.load(inboxOwnerRaw.get("profile")!);
327
+
328
+ if (inboxOwnerProfileRaw === "unavailable") {
329
+ throw new Error("Failed to load the inbox owner profile");
330
+ }
331
+
332
+ const inboxInvite = inboxOwnerProfileRaw.get("inboxInvite");
333
+
334
+ if (!inboxInvite) {
335
+ throw new Error("The user has not set up their inbox");
336
+ }
337
+
338
+ const id = await acceptInvite(inboxInvite as InboxInvite, currentAccount);
339
+
340
+ const messages = await node.load(id);
341
+
342
+ if (messages === "unavailable") {
343
+ throw new Error("Inbox not found");
344
+ }
345
+
346
+ return new InboxSender<I, O>(currentAccount, inboxOwnerRaw, messages);
347
+ }
348
+ }
349
+
350
+ async function acceptInvite(invite: string, account: Account) {
351
+ const id = invite.slice(0, invite.indexOf("/")) as CoID<MessagesStream>;
352
+
353
+ const inviteSecret = invite.slice(invite.indexOf("/") + 1) as InviteSecret;
354
+
355
+ if (!id?.startsWith("co_z") || !inviteSecret.startsWith("inviteSecret_")) {
356
+ throw new Error("Invalid inbox ticket");
357
+ }
358
+
359
+ if (!account.isMe) {
360
+ throw new Error("Account is not controlled");
361
+ }
362
+
363
+ await (account._raw as RawControlledAccount).acceptInvite(id, inviteSecret);
364
+
365
+ return id;
366
+ }
367
+
368
+ function getAccountIDfromSessionID(sessionID: SessionID) {
369
+ const until = sessionID.indexOf("_session");
370
+ const accountID = sessionID.slice(0, until);
371
+
372
+ if (accountID.startsWith("co_z")) {
373
+ return accountID as ID<Account>;
374
+ }
375
+
376
+ return;
377
+ }
@@ -1,17 +1,18 @@
1
1
  import type { CojsonInternalTypes, RawCoValue } from "cojson";
2
2
  import { RawAccount } from "cojson";
3
+ import { AnonymousJazzAgent } from "../implementation/anonymousJazzAgent.js";
3
4
  import type { DeeplyLoaded, DepthsIn } from "../internal.js";
4
5
  import {
5
- Account,
6
- AnonymousJazzAgent,
7
- Group,
8
6
  Ref,
9
7
  SubscriptionScope,
10
8
  inspect,
11
9
  subscriptionsScopes,
12
10
  } from "../internal.js";
13
11
  import { coValuesCache } from "../lib/cache.js";
12
+ import { type Account } from "./account.js";
14
13
  import { fulfillsDepth } from "./deepLoading.js";
14
+ import { type Group } from "./group.js";
15
+ import { RegisteredSchemas } from "./registeredSchemas.js";
15
16
 
16
17
  /** @category Abstract interfaces */
17
18
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -85,8 +86,8 @@ export class CoValueBase implements CoValue {
85
86
  get _owner(): Account | Group {
86
87
  const owner =
87
88
  this._raw.group instanceof RawAccount
88
- ? Account.fromRaw(this._raw.group)
89
- : Group.fromRaw(this._raw.group);
89
+ ? RegisteredSchemas["Account"].fromRaw(this._raw.group)
90
+ : RegisteredSchemas["Group"].fromRaw(this._raw.group);
90
91
 
91
92
  const subScope = subscriptionsScopes.get(this);
92
93
  if (subScope) {
@@ -102,7 +103,9 @@ export class CoValueBase implements CoValue {
102
103
  const rawAccount = this._raw.core.node.account;
103
104
 
104
105
  if (rawAccount instanceof RawAccount) {
105
- return coValuesCache.get(rawAccount, () => Account.fromRaw(rawAccount));
106
+ return coValuesCache.get(rawAccount, () =>
107
+ RegisteredSchemas["Account"].fromRaw(rawAccount),
108
+ );
106
109
  }
107
110
 
108
111
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -0,0 +1,11 @@
1
+ import { CoID } from "cojson";
2
+ import { co } from "../internal.js";
3
+ import { CoMap } from "./coMap.js";
4
+ import { InboxInvite, InboxRoot } from "./inbox.js";
5
+
6
+ /** @category Identity & Permissions */
7
+ export class Profile extends CoMap {
8
+ name = co.string;
9
+ inbox = co.optional.json<CoID<InboxRoot>>();
10
+ inboxInvite = co.optional.json<InboxInvite>();
11
+ }
@@ -0,0 +1,12 @@
1
+ import type { Account } from "./account.js";
2
+ import type { CoMap } from "./coMap.js";
3
+ import type { Group } from "./group.js";
4
+
5
+ /**
6
+ * Regisering schemas into this Record to avoid circular dependencies.
7
+ */
8
+ export const RegisteredSchemas = {} as {
9
+ Account: typeof Account;
10
+ Group: typeof Group;
11
+ CoMap: typeof CoMap;
12
+ };
package/src/exports.ts CHANGED
@@ -12,25 +12,31 @@ export type { CoValue, ID } from "./internal.js";
12
12
 
13
13
  export { Encoders, co } from "./internal.js";
14
14
 
15
+ export {
16
+ Inbox,
17
+ InboxSender,
18
+ } from "./coValues/inbox.js";
19
+
15
20
  export {
16
21
  Account,
17
- FileStream,
18
- BinaryCoStream,
19
- CoList,
20
- CoMap,
21
- CoFeed,
22
- CoStream,
23
- CoValueBase,
24
- Group,
25
- ImageDefinition,
26
- Profile,
27
22
  isControlledAccount,
28
- SchemaUnion,
29
23
  type AccountClass,
30
- type CoMapInit,
31
- type CoValueClass,
32
- } from "./internal.js";
33
- export type { DeeplyLoaded, DepthsIn } from "./internal.js";
24
+ } from "./coValues/account.js";
25
+ export { Group } from "./coValues/group.js";
26
+ export {
27
+ CoStream,
28
+ CoFeed,
29
+ FileStream,
30
+ BinaryCoStream,
31
+ } from "./coValues/coFeed.js";
32
+ export { CoList } from "./coValues/coList.js";
33
+ export { CoMap, type CoMapInit } from "./coValues/coMap.js";
34
+ export { CoValueBase } from "./coValues/interfaces.js";
35
+ export { ImageDefinition } from "./coValues/extensions/imageDef.js";
36
+ export { Profile } from "./coValues/profile.js";
37
+ export { SchemaUnion } from "./coValues/schemaUnion.js";
38
+
39
+ export type { CoValueClass, DeeplyLoaded, DepthsIn } from "./internal.js";
34
40
 
35
41
  export {
36
42
  createCoValueObservable,
@@ -0,0 +1,6 @@
1
+ import { LocalNode } from "cojson";
2
+
3
+ export class AnonymousJazzAgent {
4
+ _type = "Anonymous" as const;
5
+ constructor(public node: LocalNode) {}
6
+ }
@@ -9,7 +9,10 @@ import {
9
9
  RawAccountID,
10
10
  SessionID,
11
11
  } from "cojson";
12
- import { Account, AccountClass, ID } from "../internal.js";
12
+ import { type Account, type AccountClass } from "../coValues/account.js";
13
+ import { RegisteredSchemas } from "../coValues/registeredSchemas.js";
14
+ import type { ID } from "../internal.js";
15
+ import { AnonymousJazzAgent } from "./anonymousJazzAgent.js";
13
16
 
14
17
  export type Credentials = {
15
18
  accountID: ID<Account>;
@@ -136,7 +139,8 @@ export async function createJazzContext<Acc extends Account>(
136
139
 
137
140
  const { auth, sessionProvider, peersToLoadFrom, crypto } = options;
138
141
  const AccountSchema =
139
- options.AccountSchema ?? (Account as unknown as AccountClass<Acc>);
142
+ options.AccountSchema ??
143
+ (RegisteredSchemas["Account"] as unknown as AccountClass<Acc>);
140
144
  let authResult: AuthResult;
141
145
  try {
142
146
  authResult = await auth.start(crypto);
@@ -165,7 +169,7 @@ export async function createJazzContext<Acc extends Account>(
165
169
  fromRaw: rawAccount,
166
170
  }) as Acc;
167
171
 
168
- await account.migrate?.(creationProps);
172
+ await account.applyMigration(creationProps);
169
173
  },
170
174
  });
171
175
 
@@ -214,7 +218,7 @@ export async function createJazzContext<Acc extends Account>(
214
218
  fromRaw: rawAccount,
215
219
  }) as Acc;
216
220
 
217
- await account.migrate?.(creationProps);
221
+ await account.applyMigration(creationProps);
218
222
  },
219
223
  });
220
224
 
@@ -243,11 +247,6 @@ export async function createJazzContext<Acc extends Account>(
243
247
  }
244
248
  }
245
249
 
246
- export class AnonymousJazzAgent {
247
- _type = "Anonymous" as const;
248
- constructor(public node: LocalNode) {}
249
- }
250
-
251
250
  export async function createAnonymousJazzContext({
252
251
  peersToLoadFrom,
253
252
  crypto,
@@ -1,6 +1,6 @@
1
1
  import type { CoID, RawCoValue } from "cojson";
2
+ import { type Account } from "../coValues/account.js";
2
3
  import type {
3
- Account,
4
4
  AnonymousJazzAgent,
5
5
  CoValue,
6
6
  ID,
@@ -1,6 +1,6 @@
1
1
  import type { RawCoValue } from "cojson";
2
+ import { type Account } from "../coValues/account.js";
2
3
  import type {
3
- Account,
4
4
  AnonymousJazzAgent,
5
5
  CoValue,
6
6
  CoValueClass,
@@ -2,6 +2,5 @@ export * from "./exports.js";
2
2
 
3
3
  export {
4
4
  MAX_RECOMMENDED_TX_SIZE,
5
- PureJSCrypto,
6
5
  cojsonInternals,
7
6
  } from "cojson/native";
package/src/internal.ts CHANGED
@@ -2,21 +2,13 @@ export * from "./implementation/symbols.js";
2
2
  export * from "./implementation/inspect.js";
3
3
  export * from "./coValues/interfaces.js";
4
4
 
5
- export * from "./coValues/coMap.js";
6
- export * from "./coValues/account.js";
7
- export * from "./coValues/coList.js";
8
- export * from "./coValues/coFeed.js";
9
- export * from "./coValues/schemaUnion.js";
10
- export * from "./coValues/group.js";
11
-
12
5
  export * from "./implementation/errors.js";
6
+ export * from "./implementation/anonymousJazzAgent.js";
13
7
  export * from "./implementation/refs.js";
14
8
  export * from "./implementation/schema.js";
15
9
  export * from "./implementation/subscriptionScope.js";
16
10
  export * from "./coValues/deepLoading.js";
17
11
 
18
- export * from "./coValues/extensions/imageDef.js";
19
-
20
12
  export * from "./implementation/createContext.js";
21
13
 
22
14
  import "./implementation/devtoolsFormatters.js";
@@ -1,6 +1,6 @@
1
1
  import { expect, test } from "vitest";
2
- import { CoMap, co } from "../internal";
3
- import { setupTwoNodes } from "./utils";
2
+ import { CoMap, co } from "../exports.js";
3
+ import { setupTwoNodes } from "./utils.js";
4
4
 
5
5
  test("waitForAllCoValuesSync should resolve when all the values are synced", async () => {
6
6
  class TestMap extends CoMap {
@@ -192,15 +192,6 @@ describe("CoFeed resolution", async () => {
192
192
  const queue = new cojsonInternals.Channel();
193
193
 
194
194
  TestStream.subscribe(stream.id, meOnSecondPeer, [], (subscribedStream) => {
195
- console.log("subscribedStream[me.id]", subscribedStream[me.id]);
196
- console.log(
197
- "subscribedStream[me.id]?.value?.[me.id]?.value",
198
- subscribedStream[me.id]?.value?.[me.id]?.value,
199
- );
200
- console.log(
201
- "subscribedStream[me.id]?.value?.[me.id]?.value?.[me.id]?.value",
202
- subscribedStream[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
203
- );
204
195
  void queue.push(subscribedStream);
205
196
  });
206
197
 
@@ -1,5 +1,6 @@
1
1
  import { connectedPeers } from "cojson/src/streamUtils.ts";
2
2
  import { describe, expect, expectTypeOf, test } from "vitest";
3
+ import { Group, randomSessionProvider } from "../exports.js";
3
4
  import {
4
5
  Account,
5
6
  CoMap,
@@ -11,8 +12,7 @@ import {
11
12
  fixedCredentialsAuth,
12
13
  isControlledAccount,
13
14
  } from "../index.web.js";
14
- import { Group, randomSessionProvider } from "../internal.js";
15
- import { loadCoValueOrFail, setupTwoNodes } from "./utils.js";
15
+ import { setupTwoNodes } from "./utils.js";
16
16
 
17
17
  const Crypto = await WasmCrypto.create();
18
18
 
@@ -38,8 +38,6 @@ describe("Simple CoMap operations", async () => {
38
38
  crypto: Crypto,
39
39
  });
40
40
 
41
- console.log("TestMap schema", TestMap.prototype._schema);
42
-
43
41
  const birthday = new Date();
44
42
 
45
43
  const map = TestMap.create(
@@ -82,6 +80,13 @@ describe("Simple CoMap operations", async () => {
82
80
  expect(mapWithExtra.color).toEqual("red");
83
81
  });
84
82
 
83
+ test("Empty schema", () => {
84
+ const emptyMap = CoMap.create({}, { owner: me });
85
+
86
+ // @ts-expect-error
87
+ expect(emptyMap.color).toEqual(undefined);
88
+ });
89
+
85
90
  describe("Mutation", () => {
86
91
  test("assignment & deletion", () => {
87
92
  map.color = "blue";
@@ -468,10 +473,8 @@ describe("CoMap resolution", async () => {
468
473
  const queue = new cojsonInternals.Channel<TestMap>();
469
474
 
470
475
  TestMap.subscribe(map.id, meOnSecondPeer, {}, (subscribedMap) => {
471
- console.log(
472
- "subscribedMap.nested?.twiceNested?.taste",
473
- subscribedMap.nested?.twiceNested?.taste,
474
- );
476
+ // Read to property to trigger loading
477
+ subscribedMap.nested?.twiceNested?.taste;
475
478
  void queue.push(subscribedMap);
476
479
  });
477
480