cojson 0.2.2 → 0.3.0-alpha.0

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 (85) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/dist/account.d.ts +8 -8
  3. package/dist/account.js +2 -2
  4. package/dist/account.js.map +1 -1
  5. package/dist/coValue.d.ts +22 -27
  6. package/dist/coValue.js +21 -0
  7. package/dist/coValue.js.map +1 -1
  8. package/dist/coValueCore.d.ts +7 -7
  9. package/dist/coValueCore.js +11 -14
  10. package/dist/coValueCore.js.map +1 -1
  11. package/dist/coValues/coList.d.ts +107 -42
  12. package/dist/coValues/coList.js +163 -72
  13. package/dist/coValues/coList.js.map +1 -1
  14. package/dist/coValues/coMap.d.ts +109 -50
  15. package/dist/coValues/coMap.js +161 -109
  16. package/dist/coValues/coMap.js.map +1 -1
  17. package/dist/coValues/coStream.d.ts +78 -33
  18. package/dist/coValues/coStream.js +134 -53
  19. package/dist/coValues/coStream.js.map +1 -1
  20. package/dist/crypto.d.ts +8 -3
  21. package/dist/crypto.js +6 -6
  22. package/dist/crypto.js.map +1 -1
  23. package/dist/group.d.ts +59 -23
  24. package/dist/group.js +83 -25
  25. package/dist/group.js.map +1 -1
  26. package/dist/index.d.ts +14 -11
  27. package/dist/index.js +8 -8
  28. package/dist/index.js.map +1 -1
  29. package/dist/{node.d.ts → localNode.d.ts} +23 -11
  30. package/dist/{node.js → localNode.js} +80 -42
  31. package/dist/localNode.js.map +1 -0
  32. package/dist/media.d.ts +1 -2
  33. package/dist/permissions.js +6 -3
  34. package/dist/permissions.js.map +1 -1
  35. package/dist/queriedCoValues/queriedCoList.d.ts +66 -0
  36. package/dist/queriedCoValues/queriedCoList.js +120 -0
  37. package/dist/queriedCoValues/queriedCoList.js.map +1 -0
  38. package/dist/queriedCoValues/queriedCoMap.d.ts +47 -0
  39. package/dist/queriedCoValues/queriedCoMap.js +83 -0
  40. package/dist/queriedCoValues/queriedCoMap.js.map +1 -0
  41. package/dist/queriedCoValues/queriedCoStream.d.ts +40 -0
  42. package/dist/queriedCoValues/queriedCoStream.js +72 -0
  43. package/dist/queriedCoValues/queriedCoStream.js.map +1 -0
  44. package/dist/queries.d.ts +31 -0
  45. package/dist/queries.js +77 -0
  46. package/dist/queries.js.map +1 -0
  47. package/dist/sync.d.ts +1 -1
  48. package/dist/sync.js +1 -1
  49. package/dist/sync.js.map +1 -1
  50. package/dist/{testUtils.d.ts → tests/testUtils.d.ts} +9 -9
  51. package/dist/{testUtils.js → tests/testUtils.js} +9 -7
  52. package/dist/tests/testUtils.js.map +1 -0
  53. package/package.json +2 -2
  54. package/src/account.ts +6 -6
  55. package/src/coValue.ts +65 -34
  56. package/src/coValueCore.ts +18 -22
  57. package/src/coValues/coList.ts +272 -122
  58. package/src/coValues/coMap.ts +349 -152
  59. package/src/coValues/coStream.ts +258 -94
  60. package/src/crypto.ts +37 -24
  61. package/src/group.ts +112 -46
  62. package/src/index.ts +42 -30
  63. package/src/{node.ts → localNode.ts} +117 -66
  64. package/src/media.ts +1 -2
  65. package/src/permissions.ts +15 -18
  66. package/src/queriedCoValues/queriedCoList.ts +248 -0
  67. package/src/queriedCoValues/queriedCoMap.ts +180 -0
  68. package/src/queriedCoValues/queriedCoStream.ts +125 -0
  69. package/src/queries.ts +142 -0
  70. package/src/sync.ts +2 -2
  71. package/src/{account.test.ts → tests/account.test.ts} +6 -9
  72. package/src/{coValue.test.ts → tests/coValue.test.ts} +120 -114
  73. package/src/{coValueCore.test.ts → tests/coValueCore.test.ts} +7 -7
  74. package/src/{crypto.test.ts → tests/crypto.test.ts} +19 -21
  75. package/src/{group.test.ts → tests/group.test.ts} +2 -2
  76. package/src/{permissions.test.ts → tests/permissions.test.ts} +260 -247
  77. package/src/tests/queries.test.ts +318 -0
  78. package/src/{sync.test.ts → tests/sync.test.ts} +39 -39
  79. package/src/{testUtils.ts → tests/testUtils.ts} +10 -8
  80. package/dist/coValues/static.d.ts +0 -14
  81. package/dist/coValues/static.js +0 -20
  82. package/dist/coValues/static.js.map +0 -1
  83. package/dist/node.js.map +0 -1
  84. package/dist/testUtils.js.map +0 -1
  85. package/src/coValues/static.ts +0 -31
package/src/group.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CoID, CoValueImpl } from "./coValue.js";
1
+ import { CoID, CoValue, AnyCoValue, AnyCoMap, AnyCoList } from "./coValue.js";
2
2
  import { CoMap } from "./coValues/coMap.js";
3
3
  import { JsonObject, JsonValue } from "./jsonValue.js";
4
4
  import {
@@ -15,18 +15,21 @@ import {
15
15
  agentSecretFromSecretSeed,
16
16
  getAgentID,
17
17
  } from "./crypto.js";
18
- import { LocalNode } from "./node.js";
18
+ import { LocalNode } from "./localNode.js";
19
19
  import { AgentID, SessionID, isAgentID } from "./ids.js";
20
20
  import { AccountID, GeneralizedControlledAccount, Profile } from "./account.js";
21
21
  import { Role } from "./permissions.js";
22
22
  import { base58 } from "@scure/base";
23
- import { CoList } from "./coValues/coList.js";
24
- import { BinaryCoStream, BinaryCoStreamMeta, CoStream } from "./coValues/coStream.js";
23
+ import {
24
+ BinaryCoStream,
25
+ BinaryCoStreamMeta,
26
+ CoStream,
27
+ } from "./coValues/coStream.js";
25
28
 
26
29
  export type GroupContent = {
27
- profile: CoID<Profile> | null;
30
+ profile?: CoID<Profile> | null;
28
31
  [key: AccountID | AgentID]: Role;
29
- readKey: KeyID;
32
+ readKey?: KeyID;
30
33
  [revelationFor: `${KeyID}_for_${AccountID | AgentID}`]: Sealed<KeySecret>;
31
34
  [oldKeyForNewKey: `${KeyID}_for_${KeyID}`]: Encrypted<
32
35
  KeySecret,
@@ -35,7 +38,7 @@ export type GroupContent = {
35
38
  };
36
39
 
37
40
  export function expectGroupContent(
38
- content: CoValueImpl
41
+ content: CoValue
39
42
  ): CoMap<GroupContent, JsonObject | null> {
40
43
  if (content.type !== "comap") {
41
44
  throw new Error("Expected map");
@@ -66,6 +69,7 @@ export function expectGroupContent(
66
69
  * ```
67
70
  * */
68
71
  export class Group {
72
+ /** @category 4. Underlying CoMap */
69
73
  underlyingMap: CoMap<GroupContent, JsonObject | null>;
70
74
  /** @internal */
71
75
  node: LocalNode;
@@ -79,12 +83,20 @@ export class Group {
79
83
  this.node = node;
80
84
  }
81
85
 
82
- /** Returns the `CoID` of the `Group`. */
86
+ /**
87
+ * Returns the `CoID` of the `Group`.
88
+ *
89
+ * @category 4. Underlying CoMap
90
+ */
83
91
  get id(): CoID<CoMap<GroupContent, JsonObject | null>> {
84
92
  return this.underlyingMap.id;
85
93
  }
86
94
 
87
- /** Returns the current role of a given account. */
95
+ /**
96
+ * Returns the current role of a given account.
97
+ *
98
+ * @category 1. Role reading
99
+ */
88
100
  roleOf(accountID: AccountID): Role | undefined {
89
101
  return this.roleOfInternal(accountID);
90
102
  }
@@ -94,20 +106,28 @@ export class Group {
94
106
  return this.underlyingMap.get(accountID);
95
107
  }
96
108
 
97
- /** Returns the role of the current account in the group. */
109
+ /**
110
+ * Returns the role of the current account in the group.
111
+ *
112
+ * @category 1. Role reading
113
+ */
98
114
  myRole(): Role | undefined {
99
115
  return this.roleOfInternal(this.node.account.id);
100
116
  }
101
117
 
102
- /** Directly grants a new member a role in the group. The current account must be an
103
- * admin to be able to do so. Throws otherwise. */
118
+ /**
119
+ * Directly grants a new member a role in the group. The current account must be an
120
+ * admin to be able to do so. Throws otherwise.
121
+ *
122
+ * @category 2. Role changing
123
+ */
104
124
  addMember(accountID: AccountID, role: Role) {
105
125
  this.addMemberInternal(accountID, role);
106
126
  }
107
127
 
108
128
  /** @internal */
109
129
  addMemberInternal(accountID: AccountID | AgentID, role: Role) {
110
- this.underlyingMap = this.underlyingMap.edit((map) => {
130
+ this.underlyingMap = this.underlyingMap.mutate((map) => {
111
131
  const currentReadKey = this.underlyingMap.core.getCurrentReadKey();
112
132
 
113
133
  if (!currentReadKey.secret) {
@@ -127,15 +147,15 @@ export class Group {
127
147
 
128
148
  map.set(
129
149
  `${currentReadKey.id}_for_${accountID}`,
130
- seal(
131
- currentReadKey.secret,
132
- this.underlyingMap.core.node.account.currentSealerSecret(),
133
- getAgentSealerID(agent),
134
- {
150
+ seal({
151
+ message: currentReadKey.secret,
152
+ from: this.underlyingMap.core.node.account.currentSealerSecret(),
153
+ to: getAgentSealerID(agent),
154
+ nOnceMaterial: {
135
155
  in: this.underlyingMap.core.id,
136
156
  tx: this.underlyingMap.core.nextTransactionID(),
137
- }
138
- ),
157
+ },
158
+ }),
139
159
  "trusting"
140
160
  );
141
161
  });
@@ -173,7 +193,7 @@ export class Group {
173
193
 
174
194
  const newReadKey = newRandomKeySecret();
175
195
 
176
- this.underlyingMap = this.underlyingMap.edit((map) => {
196
+ this.underlyingMap = this.underlyingMap.mutate((map) => {
177
197
  for (const readerID of currentlyPermittedReaders) {
178
198
  const reader = this.node.resolveAccountAgent(
179
199
  readerID,
@@ -182,15 +202,15 @@ export class Group {
182
202
 
183
203
  map.set(
184
204
  `${newReadKey.id}_for_${readerID}`,
185
- seal(
186
- newReadKey.secret,
187
- this.underlyingMap.core.node.account.currentSealerSecret(),
188
- getAgentSealerID(reader),
189
- {
205
+ seal({
206
+ message: newReadKey.secret,
207
+ from: this.underlyingMap.core.node.account.currentSealerSecret(),
208
+ to: getAgentSealerID(reader),
209
+ nOnceMaterial: {
190
210
  in: this.underlyingMap.core.id,
191
211
  tx: this.underlyingMap.core.nextTransactionID(),
192
- }
193
- ),
212
+ },
213
+ }),
194
214
  "trusting"
195
215
  );
196
216
  }
@@ -208,23 +228,33 @@ export class Group {
208
228
  });
209
229
  }
210
230
 
211
- /** Strips the specified member of all roles (preventing future writes in
231
+ /**
232
+ * Strips the specified member of all roles (preventing future writes in
212
233
  * the group and owned values) and rotates the read encryption key for that group
213
- * (preventing reads of new content in the group and owned values) */
234
+ * (preventing reads of new content in the group and owned values)
235
+ *
236
+ * @category 2. Role changing
237
+ */
214
238
  removeMember(accountID: AccountID) {
215
239
  this.removeMemberInternal(accountID);
216
240
  }
217
241
 
218
242
  /** @internal */
219
243
  removeMemberInternal(accountID: AccountID | AgentID) {
220
- this.underlyingMap = this.underlyingMap.edit((map) => {
244
+ this.underlyingMap = this.underlyingMap.mutate((map) => {
221
245
  map.set(accountID, "revoked", "trusting");
222
246
  });
223
247
 
224
248
  this.rotateReadKey();
225
249
  }
226
250
 
227
- /** Creates an invite for new members to indirectly join the group, allowing them to grant themselves the specified role with the InviteSecret (a string starting with "inviteSecret_") - use `LocalNode.acceptInvite()` for this purpose. */
251
+ /**
252
+ * Creates an invite for new members to indirectly join the group,
253
+ * allowing them to grant themselves the specified role with the InviteSecret
254
+ * (a string starting with "inviteSecret_") - use `LocalNode.acceptInvite()` for this purpose.
255
+ *
256
+ * @category 2. Role changing
257
+ */
228
258
  createInvite(role: "reader" | "writer" | "admin"): InviteSecret {
229
259
  const secretSeed = newRandomSecretSeed();
230
260
 
@@ -236,12 +266,22 @@ export class Group {
236
266
  return inviteSecretFromSecretSeed(secretSeed);
237
267
  }
238
268
 
239
- /** Creates a new `CoMap` within this group, with the specified specialized
240
- * `CoMap` type `M` and optional static metadata. */
241
- createMap<M extends CoMap<{ [key: string]: JsonValue | undefined; }, JsonObject | null>>(
242
- meta?: M["meta"]
269
+ /**
270
+ * Creates a new `CoMap` within this group, with the specified specialized
271
+ * `CoMap` type `M` and optional static metadata.
272
+ *
273
+ * @category 3. Value creation
274
+ */
275
+ createMap<M extends AnyCoMap>(
276
+ init?: {
277
+ [K in keyof M["_shape"]]: M["_shape"][K] extends AnyCoValue
278
+ ? M["_shape"][K] | CoID<M["_shape"][K]>
279
+ : M["_shape"][K];
280
+ },
281
+ meta?: M["meta"],
282
+ initPrivacy: "trusting" | "private" = "trusting"
243
283
  ): M {
244
- return this.node
284
+ let map = this.node
245
285
  .createCoValue({
246
286
  type: "comap",
247
287
  ruleset: {
@@ -252,14 +292,30 @@ export class Group {
252
292
  ...createdNowUnique(),
253
293
  })
254
294
  .getCurrentContent() as M;
295
+
296
+ if (init) {
297
+ for (const [key, value] of Object.entries(init)) {
298
+ map = map.set(key, value, initPrivacy);
299
+ }
300
+ }
301
+
302
+ return map;
255
303
  }
256
304
 
257
- /** Creates a new `CoList` within this group, with the specified specialized
258
- * `CoList` type `L` and optional static metadata. */
259
- createList<L extends CoList<JsonValue, JsonObject | null>>(
260
- meta?: L["meta"]
305
+ /**
306
+ * Creates a new `CoList` within this group, with the specified specialized
307
+ * `CoList` type `L` and optional static metadata.
308
+ *
309
+ * @category 3. Value creation
310
+ */
311
+ createList<L extends AnyCoList>(
312
+ init?: (L["_item"] extends CoValue
313
+ ? CoID<L["_item"]> | L["_item"]
314
+ : L["_item"])[],
315
+ meta?: L["meta"],
316
+ initPrivacy: "trusting" | "private" = "trusting"
261
317
  ): L {
262
- return this.node
318
+ let list = this.node
263
319
  .createCoValue({
264
320
  type: "colist",
265
321
  ruleset: {
@@ -270,9 +326,18 @@ export class Group {
270
326
  ...createdNowUnique(),
271
327
  })
272
328
  .getCurrentContent() as L;
329
+
330
+ if (init) {
331
+ for (const item of init) {
332
+ list = list.append(item, undefined, initPrivacy);
333
+ }
334
+ }
335
+
336
+ return list;
273
337
  }
274
338
 
275
- createStream<C extends CoStream<JsonValue, JsonObject | null>>(
339
+ /** @category 3. Value creation */
340
+ createStream<C extends CoStream<JsonValue | CoValue, JsonObject | null>>(
276
341
  meta?: C["meta"]
277
342
  ): C {
278
343
  return this.node
@@ -288,9 +353,10 @@ export class Group {
288
353
  .getCurrentContent() as C;
289
354
  }
290
355
 
291
- createBinaryStream<
292
- C extends BinaryCoStream<BinaryCoStreamMeta>
293
- >(meta: C["meta"] = { type: "binary" }): C {
356
+ /** @category 3. Value creation */
357
+ createBinaryStream<C extends BinaryCoStream<BinaryCoStreamMeta>>(
358
+ meta: C["meta"] = { type: "binary" }
359
+ ): C {
294
360
  return this.node
295
361
  .createCoValue({
296
362
  type: "costream",
package/src/index.ts CHANGED
@@ -1,13 +1,17 @@
1
- import { CoValueCore, newRandomSessionID, MAX_RECOMMENDED_TX_SIZE } from "./coValueCore.js";
2
- import { LocalNode } from "./node.js";
3
- import type { CoValue, ReadableCoValue } from "./coValue.js";
4
- import { CoMap, WriteableCoMap } from "./coValues/coMap.js";
5
- import { CoList, WriteableCoList } from "./coValues/coList.js";
1
+ import {
2
+ CoValueCore,
3
+ newRandomSessionID,
4
+ MAX_RECOMMENDED_TX_SIZE,
5
+ } from "./coValueCore.js";
6
+ import { LocalNode } from "./localNode.js";
7
+ import type { CoValue } from "./coValue.js";
8
+ import { CoMap, MutableCoMap } from "./coValues/coMap.js";
9
+ import { CoList, MutableCoList } from "./coValues/coList.js";
6
10
  import {
7
11
  CoStream,
8
- WriteableCoStream,
12
+ MutableCoStream,
9
13
  BinaryCoStream,
10
- WriteableBinaryCoStream,
14
+ MutableBinaryCoStream,
11
15
  } from "./coValues/coStream.js";
12
16
  import {
13
17
  agentSecretFromBytes,
@@ -18,7 +22,7 @@ import {
18
22
  agentSecretFromSecretSeed,
19
23
  secretSeedLength,
20
24
  shortHashLength,
21
- cryptoReady
25
+ cryptoReady,
22
26
  } from "./crypto.js";
23
27
  import { connectedPeers } from "./streamUtils.js";
24
28
  import { AnonymousControlledAccount, ControlledAccount } from "./account.js";
@@ -28,16 +32,23 @@ import { base64URLtoBytes, bytesToBase64url } from "./base64url.js";
28
32
  import { parseJSON } from "./jsonStringify.js";
29
33
 
30
34
  import type { SessionID, AgentID } from "./ids.js";
31
- import type { CoID, CoValueImpl } from "./coValue.js";
32
- import type { BinaryChunkInfo, BinaryCoStreamMeta } from "./coValues/coStream.js";
35
+ import type { CoID, AnyCoValue } from "./coValue.js";
36
+ import type { Queried } from "./queries.js";
37
+ import type { QueriedCoStream } from "./queriedCoValues/queriedCoStream.js";
38
+ import type { QueriedCoList } from "./queriedCoValues/queriedCoList.js";
39
+ import type { QueriedCoMap } from "./queriedCoValues/queriedCoMap.js";
40
+ import type {
41
+ BinaryStreamInfo,
42
+ BinaryCoStreamMeta,
43
+ } from "./coValues/coStream.js";
33
44
  import type { JsonValue } from "./jsonValue.js";
34
45
  import type { SyncMessage, Peer } from "./sync.js";
35
46
  import type { AgentSecret } from "./crypto.js";
36
- import type { AccountID, Profile } from "./account.js";
47
+ import type { AccountID, Account, Profile } from "./account.js";
37
48
  import type { InviteSecret } from "./group.js";
38
49
  import type * as Media from "./media.js";
39
50
 
40
- type Value = JsonValue | CoValueImpl;
51
+ type Value = JsonValue | AnyCoValue;
41
52
 
42
53
  /** @hidden */
43
54
  export const cojsonInternals = {
@@ -56,45 +67,46 @@ export const cojsonInternals = {
56
67
  expectGroupContent,
57
68
  base64URLtoBytes,
58
69
  bytesToBase64url,
59
- parseJSON
70
+ parseJSON,
60
71
  };
61
72
 
62
73
  export {
63
74
  LocalNode,
64
75
  Group,
65
76
  CoMap,
66
- WriteableCoMap,
77
+ MutableCoMap,
67
78
  CoList,
68
- WriteableCoList,
79
+ MutableCoList,
69
80
  CoStream,
70
- WriteableCoStream,
81
+ MutableCoStream,
71
82
  BinaryCoStream,
72
- WriteableBinaryCoStream,
83
+ MutableBinaryCoStream,
84
+ CoValue,
85
+ CoID,
86
+ AnyCoValue,
87
+ Queried,
88
+ QueriedCoMap,
89
+ QueriedCoList,
90
+ QueriedCoStream,
91
+ AccountID,
92
+ Account,
93
+ Profile,
94
+ SessionID,
95
+ Media,
73
96
  CoValueCore,
74
97
  AnonymousControlledAccount,
75
98
  ControlledAccount,
76
99
  cryptoReady as cojsonReady,
77
- MAX_RECOMMENDED_TX_SIZE
78
- };
79
-
80
- export type {
100
+ MAX_RECOMMENDED_TX_SIZE,
81
101
  Value,
82
102
  JsonValue,
83
- CoValue,
84
- ReadableCoValue,
85
- CoValueImpl,
86
- CoID,
87
- AccountID,
88
- Profile,
89
- SessionID,
90
103
  Peer,
91
- BinaryChunkInfo,
104
+ BinaryStreamInfo,
92
105
  BinaryCoStreamMeta,
93
106
  AgentID,
94
107
  AgentSecret,
95
108
  InviteSecret,
96
109
  SyncMessage,
97
- Media
98
110
  };
99
111
 
100
112
  // eslint-disable-next-line @typescript-eslint/no-namespace