cojson 0.6.6 → 0.7.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 (56) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/.turbo/turbo-build.log +35 -0
  3. package/CHANGELOG.md +6 -0
  4. package/dist/coValue.js.map +1 -1
  5. package/dist/coValueCore.js.map +1 -1
  6. package/dist/coValues/account.js +5 -5
  7. package/dist/coValues/account.js.map +1 -1
  8. package/dist/coValues/coList.js +39 -58
  9. package/dist/coValues/coList.js.map +1 -1
  10. package/dist/coValues/coMap.js +20 -61
  11. package/dist/coValues/coMap.js.map +1 -1
  12. package/dist/coValues/coStream.js +14 -64
  13. package/dist/coValues/coStream.js.map +1 -1
  14. package/dist/coValues/group.js +57 -59
  15. package/dist/coValues/group.js.map +1 -1
  16. package/dist/coreToCoValue.js +17 -12
  17. package/dist/coreToCoValue.js.map +1 -1
  18. package/dist/index.js +8 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/localNode.js +54 -38
  21. package/dist/localNode.js.map +1 -1
  22. package/dist/permissions.js +2 -2
  23. package/dist/permissions.js.map +1 -1
  24. package/dist/sync.js +3 -3
  25. package/dist/sync.js.map +1 -1
  26. package/dist/tests/testUtils.js +6 -11
  27. package/dist/tests/testUtils.js.map +1 -1
  28. package/dist/typeUtils/expectGroup.js +2 -2
  29. package/dist/typeUtils/expectGroup.js.map +1 -1
  30. package/dist/typeUtils/isCoValue.js +8 -8
  31. package/dist/typeUtils/isCoValue.js.map +1 -1
  32. package/package.json +52 -53
  33. package/src/coValue.ts +21 -21
  34. package/src/coValueCore.ts +8 -8
  35. package/src/coValues/account.ts +14 -26
  36. package/src/coValues/coList.ts +58 -97
  37. package/src/coValues/coMap.ts +27 -129
  38. package/src/coValues/coStream.ts +31 -137
  39. package/src/coValues/group.ts +52 -46
  40. package/src/coreToCoValue.ts +16 -12
  41. package/src/index.ts +27 -36
  42. package/src/jsonValue.ts +1 -1
  43. package/src/localNode.ts +88 -75
  44. package/src/media.ts +4 -4
  45. package/src/permissions.ts +2 -2
  46. package/src/sync.ts +3 -3
  47. package/src/tests/account.test.ts +12 -12
  48. package/src/tests/coValue.test.ts +149 -182
  49. package/src/tests/coValueCore.test.ts +8 -3
  50. package/src/tests/crypto.test.ts +7 -0
  51. package/src/tests/group.test.ts +13 -6
  52. package/src/tests/permissions.test.ts +648 -840
  53. package/src/tests/sync.test.ts +44 -68
  54. package/src/tests/testUtils.ts +6 -11
  55. package/src/typeUtils/expectGroup.ts +4 -4
  56. package/src/typeUtils/isCoValue.ts +11 -11
@@ -1,8 +1,8 @@
1
1
  import { CoID } from "../coValue.js";
2
- import { CoMap } from "./coMap.js";
3
- import { CoList } from "./coList.js";
2
+ import { RawCoMap } from "./coMap.js";
3
+ import { RawCoList } from "./coList.js";
4
4
  import { JsonObject } from "../jsonValue.js";
5
- import { BinaryCoStream, CoStream } from "./coStream.js";
5
+ import { RawBinaryCoStream, RawCoStream } from "./coStream.js";
6
6
  import {
7
7
  Encrypted,
8
8
  KeyID,
@@ -18,16 +18,20 @@ import {
18
18
  getAgentID,
19
19
  } from "../crypto.js";
20
20
  import { AgentID, isAgentID } from "../ids.js";
21
- import { Account, AccountID, ControlledAccountOrAgent, Profile } from "./account.js";
21
+ import {
22
+ RawAccount,
23
+ AccountID,
24
+ ControlledAccountOrAgent,
25
+ } from "./account.js";
22
26
  import { Role } from "../permissions.js";
23
27
  import { base58 } from "@scure/base";
24
28
 
25
29
  export const EVERYONE = "everyone" as const;
26
30
  export type Everyone = "everyone";
27
31
 
28
- export type GroupShape<P extends Profile, R extends CoMap> = {
29
- profile?: CoID<P> | null;
30
- root?: CoID<R> | null;
32
+ export type GroupShape = {
33
+ profile: CoID<RawCoMap> | null;
34
+ root: CoID<RawCoMap> | null;
31
35
  [key: AccountID | AgentID]: Role;
32
36
  [EVERYONE]?: Role;
33
37
  readKey?: KeyID;
@@ -60,11 +64,9 @@ export type GroupShape<P extends Profile, R extends CoMap> = {
60
64
  * const localNode.createGroup();
61
65
  * ```
62
66
  * */
63
- export class Group<
64
- P extends Profile = Profile,
65
- R extends CoMap = CoMap,
67
+ export class RawGroup<
66
68
  Meta extends JsonObject | null = JsonObject | null
67
- > extends CoMap<GroupShape<P, R>, Meta> {
69
+ > extends RawCoMap<GroupShape, Meta> {
68
70
  /**
69
71
  * Returns the current role of a given account.
70
72
  *
@@ -94,16 +96,18 @@ export class Group<
94
96
  *
95
97
  * @category 2. Role changing
96
98
  */
97
- addMember(account: Account | ControlledAccountOrAgent | Everyone, role: Role): this {
98
- return this.addMemberInternal(account, role);
99
+ addMember(
100
+ account: RawAccount | ControlledAccountOrAgent | Everyone,
101
+ role: Role
102
+ ) {
103
+ this.addMemberInternal(account, role);
99
104
  }
100
105
 
101
106
  /** @internal */
102
107
  addMemberInternal(
103
- account: Account | ControlledAccountOrAgent | AgentID | Everyone,
108
+ account: RawAccount | ControlledAccountOrAgent | AgentID | Everyone,
104
109
  role: Role
105
- ): this {
106
- return this.mutate((mutable) => {
110
+ ) {
107
111
  const currentReadKey = this.core.getCurrentReadKey();
108
112
 
109
113
  if (!currentReadKey.secret) {
@@ -116,27 +120,31 @@ export class Group<
116
120
  "Can't make everyone something other than reader or writer"
117
121
  );
118
122
  }
119
- mutable.set(account, role, "trusting");
123
+ this.set(account, role, "trusting");
120
124
 
121
- if (mutable.get(account) !== role) {
125
+ if (this.get(account) !== role) {
122
126
  throw new Error("Failed to set role");
123
127
  }
124
128
 
125
- mutable.set(
129
+ this.set(
126
130
  `${currentReadKey.id}_for_${EVERYONE}`,
127
131
  currentReadKey.secret,
128
132
  "trusting"
129
133
  );
130
134
  } else {
131
- const memberKey = typeof account === "string" ? account : account.id;
132
- const agent = typeof account === "string" ? account : account.currentAgentID();
133
- mutable.set(memberKey, role, "trusting");
134
-
135
- if (mutable.get(memberKey) !== role) {
135
+ const memberKey =
136
+ typeof account === "string" ? account : account.id;
137
+ const agent =
138
+ typeof account === "string"
139
+ ? account
140
+ : account.currentAgentID();
141
+ this.set(memberKey, role, "trusting");
142
+
143
+ if (this.get(memberKey) !== role) {
136
144
  throw new Error("Failed to set role");
137
145
  }
138
146
 
139
- mutable.set(
147
+ this.set(
140
148
  `${currentReadKey.id}_for_${memberKey}`,
141
149
  seal({
142
150
  message: currentReadKey.secret,
@@ -150,11 +158,10 @@ export class Group<
150
158
  "trusting"
151
159
  );
152
160
  }
153
- });
154
161
  }
155
162
 
156
163
  /** @internal */
157
- rotateReadKey(): this {
164
+ rotateReadKey() {
158
165
  const currentlyPermittedReaders = this.keys().filter((key) => {
159
166
  if (key.startsWith("co_") || isAgentID(key)) {
160
167
  const role = this.get(key);
@@ -181,14 +188,13 @@ export class Group<
181
188
 
182
189
  const newReadKey = newRandomKeySecret();
183
190
 
184
- return this.mutate((mutable) => {
185
191
  for (const readerID of currentlyPermittedReaders) {
186
192
  const reader = this.core.node.resolveAccountAgent(
187
193
  readerID,
188
194
  "Expected to know currently permitted reader"
189
195
  );
190
196
 
191
- mutable.set(
197
+ this.set(
192
198
  `${newReadKey.id}_for_${readerID}`,
193
199
  seal({
194
200
  message: newReadKey.secret,
@@ -203,7 +209,7 @@ export class Group<
203
209
  );
204
210
  }
205
211
 
206
- mutable.set(
212
+ this.set(
207
213
  `${currentReadKey.id}_for_${newReadKey.id}`,
208
214
  encryptKeySecret({
209
215
  encrypting: newReadKey,
@@ -212,8 +218,7 @@ export class Group<
212
218
  "trusting"
213
219
  );
214
220
 
215
- mutable.set("readKey", newReadKey.id, "trusting");
216
- });
221
+ this.set("readKey", newReadKey.id, "trusting");
217
222
  }
218
223
 
219
224
  /**
@@ -223,16 +228,17 @@ export class Group<
223
228
  *
224
229
  * @category 2. Role changing
225
230
  */
226
- removeMember(account: Account | ControlledAccountOrAgent | Everyone): this {
227
- return this.removeMemberInternal(account);
231
+ removeMember(account: RawAccount | ControlledAccountOrAgent | Everyone) {
232
+ this.removeMemberInternal(account);
228
233
  }
229
234
 
230
235
  /** @internal */
231
- removeMemberInternal(account: Account | ControlledAccountOrAgent | AgentID | Everyone): this {
236
+ removeMemberInternal(
237
+ account: RawAccount | ControlledAccountOrAgent | AgentID | Everyone
238
+ ) {
232
239
  const memberKey = typeof account === "string" ? account : account.id;
233
- const afterRevoke = this.set(memberKey, "revoked", "trusting");
234
-
235
- return afterRevoke.rotateReadKey();
240
+ this.set(memberKey, "revoked", "trusting");
241
+ this.rotateReadKey();
236
242
  }
237
243
 
238
244
  /**
@@ -259,12 +265,12 @@ export class Group<
259
265
  *
260
266
  * @category 3. Value creation
261
267
  */
262
- createMap<M extends CoMap>(
268
+ createMap<M extends RawCoMap>(
263
269
  init?: M["_shape"],
264
270
  meta?: M["headerMeta"],
265
271
  initPrivacy: "trusting" | "private" = "private"
266
272
  ): M {
267
- let map = this.core.node
273
+ const map = this.core.node
268
274
  .createCoValue({
269
275
  type: "comap",
270
276
  ruleset: {
@@ -278,7 +284,7 @@ export class Group<
278
284
 
279
285
  if (init) {
280
286
  for (const [key, value] of Object.entries(init)) {
281
- map = map.set(key, value, initPrivacy);
287
+ map.set(key, value, initPrivacy);
282
288
  }
283
289
  }
284
290
 
@@ -291,12 +297,12 @@ export class Group<
291
297
  *
292
298
  * @category 3. Value creation
293
299
  */
294
- createList<L extends CoList>(
300
+ createList<L extends RawCoList>(
295
301
  init?: L["_item"][],
296
302
  meta?: L["headerMeta"],
297
303
  initPrivacy: "trusting" | "private" = "private"
298
304
  ): L {
299
- let list = this.core.node
305
+ const list = this.core.node
300
306
  .createCoValue({
301
307
  type: "colist",
302
308
  ruleset: {
@@ -310,7 +316,7 @@ export class Group<
310
316
 
311
317
  if (init) {
312
318
  for (const item of init) {
313
- list = list.append(item, undefined, initPrivacy);
319
+ list.append(item, undefined, initPrivacy);
314
320
  }
315
321
  }
316
322
 
@@ -318,7 +324,7 @@ export class Group<
318
324
  }
319
325
 
320
326
  /** @category 3. Value creation */
321
- createStream<C extends CoStream>(meta?: C["headerMeta"]): C {
327
+ createStream<C extends RawCoStream>(meta?: C["headerMeta"]): C {
322
328
  return this.core.node
323
329
  .createCoValue({
324
330
  type: "costream",
@@ -333,7 +339,7 @@ export class Group<
333
339
  }
334
340
 
335
341
  /** @category 3. Value creation */
336
- createBinaryStream<C extends BinaryCoStream>(
342
+ createBinaryStream<C extends RawBinaryCoStream>(
337
343
  meta: C["headerMeta"] = { type: "binary" }
338
344
  ): C {
339
345
  return this.core.node
@@ -1,10 +1,10 @@
1
1
  import type { CoValueCore } from "./coValueCore.js";
2
- import { Account } from "./coValues/account.js";
3
- import { Group } from "./coValues/group.js";
4
- import { CoMap } from "./coValues/coMap.js";
5
- import { CoList } from "./coValues/coList.js";
6
- import { CoStream } from "./coValues/coStream.js";
7
- import { BinaryCoStream } from "./coValues/coStream.js";
2
+ import { RawAccount, RawControlledAccount } from "./coValues/account.js";
3
+ import { RawGroup } from "./coValues/group.js";
4
+ import { RawCoMap } from "./coValues/coMap.js";
5
+ import { RawCoList } from "./coValues/coList.js";
6
+ import { RawCoStream } from "./coValues/coStream.js";
7
+ import { RawBinaryCoStream } from "./coValues/coStream.js";
8
8
 
9
9
  export function coreToCoValue(
10
10
  core: CoValueCore,
@@ -16,20 +16,24 @@ export function coreToCoValue(
16
16
  core.header.meta?.type === "account" &&
17
17
  !options?.ignorePrivateTransactions
18
18
  ) {
19
- return new Account(core);
19
+ if (core.id === core.node.account.id) {
20
+ return new RawControlledAccount(core, core.node.account.agentSecret);
21
+ } else {
22
+ return new RawAccount(core);
23
+ }
20
24
  } else {
21
- return new Group(core, options);
25
+ return new RawGroup(core, options);
22
26
  }
23
27
  } else {
24
- return new CoMap(core);
28
+ return new RawCoMap(core);
25
29
  }
26
30
  } else if (core.header.type === "colist") {
27
- return new CoList(core);
31
+ return new RawCoList(core);
28
32
  } else if (core.header.type === "costream") {
29
33
  if (core.header.meta && core.header.meta.type === "binary") {
30
- return new BinaryCoStream(core);
34
+ return new RawBinaryCoStream(core);
31
35
  } else {
32
- return new CoStream(core);
36
+ return new RawCoStream(core);
33
37
  }
34
38
  } else {
35
39
  throw new Error(`Unknown coValue type ${core.header.type}`);
package/src/index.ts CHANGED
@@ -6,15 +6,10 @@ import {
6
6
  } from "./coValueCore.js";
7
7
  import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
8
8
  import { LocalNode } from "./localNode.js";
9
- import type { CoValue } from "./coValue.js";
10
- import { CoMap, MutableCoMap } from "./coValues/coMap.js";
11
- import { CoList, MutableCoList } from "./coValues/coList.js";
12
- import {
13
- CoStream,
14
- MutableCoStream,
15
- BinaryCoStream,
16
- MutableBinaryCoStream,
17
- } from "./coValues/coStream.js";
9
+ import type { RawCoValue } from "./coValue.js";
10
+ import { RawCoMap } from "./coValues/coMap.js";
11
+ import { RawCoList } from "./coValues/coList.js";
12
+ import { RawCoStream, RawBinaryCoStream } from "./coValues/coStream.js";
18
13
  import {
19
14
  agentSecretFromBytes,
20
15
  agentSecretToBytes,
@@ -27,22 +22,23 @@ import {
27
22
  cryptoReady,
28
23
  } from "./crypto.js";
29
24
  import { connectedPeers } from "./streamUtils.js";
30
- import {
31
- ControlledAgent,
32
- ControlledAccount,
33
- } from "./coValues/account.js";
25
+ import { ControlledAgent, RawControlledAccount } from "./coValues/account.js";
34
26
  import type { Role } from "./permissions.js";
35
27
  import { rawCoIDtoBytes, rawCoIDfromBytes } from "./ids.js";
36
- import { Group, EVERYONE } from "./coValues/group.js";
28
+ import { RawGroup, EVERYONE } from "./coValues/group.js";
37
29
  import type { Everyone } from "./coValues/group.js";
38
30
  import { base64URLtoBytes, bytesToBase64url } from "./base64url.js";
39
31
  import { parseJSON } from "./jsonStringify.js";
40
- import { Account, Profile, accountHeaderForInitialAgentSecret } from "./coValues/account.js";
32
+ import {
33
+ RawAccount,
34
+ Profile,
35
+ accountHeaderForInitialAgentSecret,
36
+ } from "./coValues/account.js";
41
37
  import { expectGroup } from "./typeUtils/expectGroup.js";
42
38
  import { isAccountID } from "./typeUtils/isAccountID.js";
43
39
 
44
40
  import type { SessionID, AgentID } from "./ids.js";
45
- import type { CoID, AnyCoValue } from "./coValue.js";
41
+ import type { CoID, AnyRawCoValue } from "./coValue.js";
46
42
  import type {
47
43
  BinaryStreamInfo,
48
44
  BinaryCoStreamMeta,
@@ -53,13 +49,13 @@ import type { AgentSecret } from "./crypto.js";
53
49
  import type {
54
50
  AccountID,
55
51
  AccountMeta,
56
- AccountMigration,
52
+ RawAccountMigration,
57
53
  ProfileMeta,
58
54
  } from "./coValues/account.js";
59
55
  import type { InviteSecret } from "./coValues/group.js";
60
56
  import type * as Media from "./media.js";
61
57
 
62
- type Value = JsonValue | AnyCoValue;
58
+ type Value = JsonValue | AnyRawCoValue;
63
59
 
64
60
  /** @hidden */
65
61
  export const cojsonInternals = {
@@ -82,37 +78,33 @@ export const cojsonInternals = {
82
78
  accountOrAgentIDfromSessionID,
83
79
  isAccountID,
84
80
  accountHeaderForInitialAgentSecret,
85
- idforHeader
81
+ idforHeader,
86
82
  };
87
83
 
88
84
  export {
89
85
  LocalNode,
90
- Group,
86
+ RawGroup,
91
87
  Role,
92
88
  EVERYONE,
93
89
  Everyone,
94
- CoMap,
95
- MutableCoMap,
96
- CoList,
97
- MutableCoList,
98
- CoStream,
99
- MutableCoStream,
100
- BinaryCoStream,
101
- MutableBinaryCoStream,
102
- CoValue,
90
+ RawCoMap,
91
+ RawCoList,
92
+ RawCoStream,
93
+ RawBinaryCoStream,
94
+ RawCoValue,
103
95
  CoID,
104
- AnyCoValue,
105
- Account,
96
+ AnyRawCoValue,
97
+ RawAccount,
106
98
  AccountID,
107
99
  AccountMeta,
108
- AccountMigration,
100
+ RawAccountMigration,
109
101
  Profile,
110
102
  ProfileMeta,
111
103
  SessionID,
112
104
  Media,
113
105
  CoValueCore,
114
106
  ControlledAgent,
115
- ControlledAccount,
107
+ RawControlledAccount,
116
108
  cryptoReady as cojsonReady,
117
109
  MAX_RECOMMENDED_TX_SIZE,
118
110
  JsonValue,
@@ -125,9 +117,7 @@ export {
125
117
  SyncMessage,
126
118
  };
127
119
 
128
- export type {
129
- Value,
130
- }
120
+ export type { Value };
131
121
 
132
122
  // eslint-disable-next-line @typescript-eslint/no-namespace
133
123
  export namespace CojsonInternalTypes {
@@ -145,4 +135,5 @@ export namespace CojsonInternalTypes {
145
135
  export type ProfileMeta = import("./coValues/account.js").ProfileMeta;
146
136
  export type SealerSecret = import("./crypto.js").SealerSecret;
147
137
  export type SignerSecret = import("./crypto.js").SignerSecret;
138
+ export type JsonObject = import("./jsonValue.js").JsonObject;
148
139
  }
package/src/jsonValue.ts CHANGED
@@ -2,5 +2,5 @@ import { RawCoID } from './ids.js';
2
2
 
3
3
  export type JsonAtom = string | number | boolean | null;
4
4
  export type JsonValue = JsonAtom | JsonArray | JsonObject | RawCoID;
5
- export type JsonArray = JsonValue[];
5
+ export type JsonArray = JsonValue[] | readonly JsonValue[];
6
6
  export type JsonObject = { [key: string]: JsonValue | undefined; };