jazz-tools 0.7.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. package/.eslintrc.cjs +24 -0
  2. package/.turbo/turbo-build.log +24 -0
  3. package/CHANGELOG.md +42 -0
  4. package/LICENSE.txt +19 -0
  5. package/README.md +3 -0
  6. package/dist/coValueInterfaces.js +8 -0
  7. package/dist/coValueInterfaces.js.map +1 -0
  8. package/dist/coValues/account/account.js +11 -0
  9. package/dist/coValues/account/account.js.map +1 -0
  10. package/dist/coValues/account/accountOf.js +150 -0
  11. package/dist/coValues/account/accountOf.js.map +1 -0
  12. package/dist/coValues/account/migration.js +4 -0
  13. package/dist/coValues/account/migration.js.map +1 -0
  14. package/dist/coValues/coList/coList.js +2 -0
  15. package/dist/coValues/coList/coList.js.map +1 -0
  16. package/dist/coValues/coList/coListOf.js +235 -0
  17. package/dist/coValues/coList/coListOf.js.map +1 -0
  18. package/dist/coValues/coList/internalDocs.js +2 -0
  19. package/dist/coValues/coList/internalDocs.js.map +1 -0
  20. package/dist/coValues/coMap/coMap.js +2 -0
  21. package/dist/coValues/coMap/coMap.js.map +1 -0
  22. package/dist/coValues/coMap/coMapOf.js +262 -0
  23. package/dist/coValues/coMap/coMapOf.js.map +1 -0
  24. package/dist/coValues/coMap/internalDocs.js +2 -0
  25. package/dist/coValues/coMap/internalDocs.js.map +1 -0
  26. package/dist/coValues/coStream/coStream.js +2 -0
  27. package/dist/coValues/coStream/coStream.js.map +1 -0
  28. package/dist/coValues/coStream/coStreamOf.js +244 -0
  29. package/dist/coValues/coStream/coStreamOf.js.map +1 -0
  30. package/dist/coValues/construction.js +34 -0
  31. package/dist/coValues/construction.js.map +1 -0
  32. package/dist/coValues/extensions/imageDef.js +36 -0
  33. package/dist/coValues/extensions/imageDef.js.map +1 -0
  34. package/dist/coValues/group/group.js +2 -0
  35. package/dist/coValues/group/group.js.map +1 -0
  36. package/dist/coValues/group/groupOf.js +109 -0
  37. package/dist/coValues/group/groupOf.js.map +1 -0
  38. package/dist/coValues/resolution.js +66 -0
  39. package/dist/coValues/resolution.js.map +1 -0
  40. package/dist/errors.js +2 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/index.js +31 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/refs.js +95 -0
  45. package/dist/refs.js.map +1 -0
  46. package/dist/schemaHelpers.js +14 -0
  47. package/dist/schemaHelpers.js.map +1 -0
  48. package/dist/subscriptionScope.js +81 -0
  49. package/dist/subscriptionScope.js.map +1 -0
  50. package/dist/tests/coList.test.js +207 -0
  51. package/dist/tests/coList.test.js.map +1 -0
  52. package/dist/tests/coMap.test.js +238 -0
  53. package/dist/tests/coMap.test.js.map +1 -0
  54. package/dist/tests/coStream.test.js +263 -0
  55. package/dist/tests/coStream.test.js.map +1 -0
  56. package/dist/tests/types.test.js +33 -0
  57. package/dist/tests/types.test.js.map +1 -0
  58. package/package.json +23 -0
  59. package/src/coValueInterfaces.ts +105 -0
  60. package/src/coValues/account/account.ts +106 -0
  61. package/src/coValues/account/accountOf.ts +284 -0
  62. package/src/coValues/account/migration.ts +12 -0
  63. package/src/coValues/coList/coList.ts +57 -0
  64. package/src/coValues/coList/coListOf.ts +377 -0
  65. package/src/coValues/coList/internalDocs.ts +1 -0
  66. package/src/coValues/coMap/coMap.ts +110 -0
  67. package/src/coValues/coMap/coMapOf.ts +451 -0
  68. package/src/coValues/coMap/internalDocs.ts +1 -0
  69. package/src/coValues/coStream/coStream.ts +63 -0
  70. package/src/coValues/coStream/coStreamOf.ts +404 -0
  71. package/src/coValues/construction.ts +110 -0
  72. package/src/coValues/extensions/imageDef.ts +51 -0
  73. package/src/coValues/group/group.ts +27 -0
  74. package/src/coValues/group/groupOf.ts +183 -0
  75. package/src/coValues/resolution.ts +111 -0
  76. package/src/errors.ts +1 -0
  77. package/src/index.ts +68 -0
  78. package/src/refs.ts +128 -0
  79. package/src/schemaHelpers.ts +72 -0
  80. package/src/subscriptionScope.ts +118 -0
  81. package/src/tests/coList.test.ts +283 -0
  82. package/src/tests/coMap.test.ts +357 -0
  83. package/src/tests/coStream.test.ts +415 -0
  84. package/src/tests/types.test.ts +37 -0
  85. package/tsconfig.json +15 -0
@@ -0,0 +1,105 @@
1
+ import { RawCoID } from "cojson/src/ids";
2
+ import {
3
+ AnyAccount,
4
+ ControlledAccount,
5
+ ControlledAccountCtx,
6
+ } from "./coValues/account/account.js";
7
+ import { CoValueCore } from "cojson";
8
+ import { Effect, Stream } from "effect";
9
+ import { UnavailableError } from "./errors.js";
10
+ import { Schema } from "@effect/schema";
11
+ import { AnyGroup } from "./coValues/group/group.js";
12
+ import { SchemaWithInputAndOutput } from "./schemaHelpers.js";
13
+
14
+ export type SubclassedConstructor<T> = {
15
+ new (...args: any[]): T;
16
+ type: string;
17
+ };
18
+
19
+ export interface CoValueConstructor<
20
+ Value extends CoValue = CoValue,
21
+ Type extends string = string,
22
+ Init = any,
23
+ > {
24
+ readonly type: Type;
25
+
26
+ /** @category Construction and loading */
27
+ new (init: Init, options: { owner: AnyAccount | AnyGroup }): Value;
28
+
29
+ /** @ignore */
30
+ fromRaw(raw: Value["_raw"]): Value;
31
+
32
+ /** @category Construction and loading */
33
+ load<V extends Value>(
34
+ this: SubclassedConstructor<V>,
35
+ id: ID<V>,
36
+ options: { as: ControlledAccount, onProgress?: (progress: number) => void }
37
+ ): Promise<V | undefined>;
38
+
39
+ /** @category Construction and loading */
40
+ loadEf<V extends Value>(
41
+ this: SubclassedConstructor<V>,
42
+ id: ID<V>
43
+ ): Effect.Effect<V, UnavailableError, ControlledAccountCtx>;
44
+
45
+ /** @category Subscription */
46
+ subscribe<V extends Value>(
47
+ this: SubclassedConstructor<V>,
48
+ id: ID<V>,
49
+ options: { as: ControlledAccount },
50
+ onUpdate: (value: V) => void
51
+ ): () => void;
52
+
53
+ /** @category Subscription */
54
+ subscribeEf<V extends Value>(
55
+ this: SubclassedConstructor<V>,
56
+ id: ID<V>
57
+ ): Stream.Stream<V, UnavailableError, ControlledAccountCtx>;
58
+ }
59
+
60
+ /** @category Schemas & CoValues - Abstract interfaces */
61
+ export interface CoValueSchema<
62
+ Self = any,
63
+ Value extends CoValue = CoValue,
64
+ Type extends string = string,
65
+ Init = any,
66
+ > extends CoValueConstructor<Value, Type, Init>,
67
+ SchemaWithInputAndOutput<Self, Self> {}
68
+
69
+ export function isCoValueSchema(value: any): value is CoValueSchema {
70
+ return value && value.type !== undefined;
71
+ }
72
+
73
+ export const inspect = Symbol.for("nodejs.util.inspect.custom");
74
+ export type inspect = typeof inspect;
75
+
76
+ /** @category Schemas & CoValues - Abstract interfaces */
77
+ export interface CoValue<Type extends string = string, Raw = any> {
78
+ /** @category Value identity */
79
+ id: ID<this>;
80
+ /** @category Value identity */
81
+ _type: Type;
82
+ /** @category Collaboration */
83
+ _owner: AnyAccount | AnyGroup;
84
+ /** @category Subscription */
85
+ subscribe(listener: (update: this) => void): () => void;
86
+ /** @category Subscription */
87
+ subscribeEf(): Stream.Stream<this, UnavailableError, never>;
88
+ /** @category Internals */
89
+ _raw: Raw;
90
+ /** @category Internals */
91
+ _loadedAs: ControlledAccount;
92
+ /** @category Internals */
93
+ _schema: CoValueSchema;
94
+ /** @category Stringifying & inspection */
95
+ toJSON(): any[] | object;
96
+ /** @category Stringifying & inspection */
97
+ [inspect](): any;
98
+ }
99
+
100
+ export function isCoValue(value: any): value is CoValue {
101
+ return value && value._type !== undefined;
102
+ }
103
+
104
+ /** @category Schemas & CoValues - Abstract interfaces */
105
+ export type ID<T> = RawCoID & { readonly __type: (_: never) => T };
@@ -0,0 +1,106 @@
1
+ import * as S from "@effect/schema/Schema";
2
+ import {
3
+ CoValue,
4
+ ID,
5
+ CoValueSchema,
6
+ SubclassedConstructor,
7
+ } from "../../coValueInterfaces.js";
8
+ import { CoMap, CoMapSchema } from "../coMap/coMap.js";
9
+ import {
10
+ AgentSecret,
11
+ InviteSecret,
12
+ Peer,
13
+ RawAccount,
14
+ RawControlledAccount,
15
+ Role,
16
+ SessionID,
17
+ } from "cojson";
18
+ import { AccountMigration } from "./migration.js";
19
+ import { Context } from "effect";
20
+ import { ValueRef } from "../../refs.js";
21
+ import { SchemaWithInputAndOutput, SchemaWithOutput } from "../../schemaHelpers.js";
22
+
23
+ export type ProfileSchema = CoMapSchema<any, {
24
+ name: S.Schema<string>
25
+ }, any> & SchemaWithInputAndOutput<CoMap<{
26
+ name: S.Schema<string>
27
+ }>>;
28
+
29
+ export type RootSchema = CoValueSchema | S.Schema<null>;
30
+
31
+ export interface AnyAccount<
32
+ P extends ProfileSchema = ProfileSchema,
33
+ R extends RootSchema = RootSchema,
34
+ > extends CoValue<"Account", RawAccount> {
35
+ profile?: S.Schema.To<P>;
36
+ root?: S.Schema.To<R>;
37
+ isMe: boolean;
38
+ _refs: {
39
+ profile: ValueRef<S.Schema.To<P>>;
40
+ root: ValueRef<S.Schema.To<R>>;
41
+ };
42
+ myRole(): 'admin';
43
+ }
44
+
45
+ export function isAccount(value: CoValue): value is AnyAccount {
46
+ return value._type === "Account";
47
+ }
48
+
49
+ export function isControlledAccount(
50
+ value: CoValue
51
+ ): value is ControlledAccount {
52
+ return isAccount(value) && value.isMe;
53
+ }
54
+
55
+ export type ControlledAccount<
56
+ P extends ProfileSchema = ProfileSchema,
57
+ R extends RootSchema = RootSchema,
58
+ > = AnyAccount<P, R> &
59
+ CoValue<"Account", RawControlledAccount> & {
60
+ isMe: true;
61
+
62
+ acceptInvite<V extends CoValueSchema>(
63
+ valueID: ID<S.Schema.To<V>>,
64
+ inviteSecret: InviteSecret,
65
+ valueSchema: V
66
+ ): Promise<S.Schema.To<V>>;
67
+
68
+ sessionID: SessionID;
69
+ };
70
+
71
+ export interface AccountSchema<
72
+ Self = any,
73
+ P extends ProfileSchema = ProfileSchema,
74
+ R extends RootSchema = RootSchema,
75
+ > extends CoValueSchema<Self, AnyAccount<P, R>, "Account", undefined> {
76
+ readonly [controlledAccountSym]: ControlledAccount<P, R>;
77
+
78
+ create<A extends AnyAccount<P, R>>(
79
+ this: SubclassedConstructor<A>,
80
+ options: {
81
+ name: string;
82
+ migration?: AccountMigration<AccountSchema<AnyAccount<P, R>, P, R>>;
83
+ initialAgentSecret?: AgentSecret;
84
+ peersToLoadFrom?: Peer[];
85
+ }
86
+ ): Promise<ControlledAccount<P, R>>;
87
+
88
+ become<A extends AnyAccount<P, R>>(
89
+ this: SubclassedConstructor<A>,
90
+ options: {
91
+ accountID: ID<AnyAccount<P, R>>;
92
+ accountSecret: AgentSecret;
93
+ sessionID: SessionID;
94
+ peersToLoadFrom: Peer[];
95
+ migration?: AccountMigration<AccountSchema<AnyAccount<P, R>, P, R>>;
96
+ }
97
+ ): Promise<ControlledAccount<P, R>>;
98
+ }
99
+
100
+ export const controlledAccountSym = Symbol("@jazz/controlledAccount");
101
+ export type controlledAccountSym = typeof controlledAccountSym;
102
+
103
+ export class ControlledAccountCtx extends Context.Tag("ControlledAccount")<
104
+ ControlledAccountCtx,
105
+ ControlledAccount
106
+ >() {}
@@ -0,0 +1,284 @@
1
+ import {
2
+ AgentSecret,
3
+ CoID,
4
+ InviteSecret,
5
+ LocalNode,
6
+ Peer,
7
+ RawAccount,
8
+ RawCoValue,
9
+ RawControlledAccount,
10
+ SessionID,
11
+ } from "cojson";
12
+ import {
13
+ ID,
14
+ CoValueSchema,
15
+ inspect,
16
+ CoValue,
17
+ } from "../../coValueInterfaces.js";
18
+ import { CoMapOf } from "../coMap/coMapOf.js";
19
+ import {
20
+ AnyAccount,
21
+ AccountSchema,
22
+ ProfileSchema,
23
+ ControlledAccount,
24
+ controlledAccountSym,
25
+ } from "./account.js";
26
+ import * as S from "@effect/schema/Schema";
27
+ import { AccountMigration } from "./migration.js";
28
+ import { AST, Schema } from "@effect/schema";
29
+ import { AnyGroup } from "../group/group.js";
30
+ import { SharedCoValueConstructor } from "../construction.js";
31
+ import { constructorOfSchemaSym } from "../resolution.js";
32
+ import { pipeArguments } from "effect/Pipeable";
33
+ import { ValueRef } from "../../refs.js";
34
+
35
+ export function AccountOf<
36
+ P extends ProfileSchema,
37
+ R extends CoValueSchema | S.Schema<null>,
38
+ >(fields: { profile: P; root: R }) {
39
+ class AccountOfProfileAndRoot
40
+ extends SharedCoValueConstructor
41
+ implements AnyAccount<P, R>
42
+ {
43
+ static get ast() {
44
+ return AST.setAnnotation(
45
+ Schema.instanceOf(this).ast,
46
+ constructorOfSchemaSym,
47
+ this
48
+ );
49
+ }
50
+ static [Schema.TypeId]: Schema.Schema.Variance<
51
+ AnyAccount<P, R> & AccountOfProfileAndRoot,
52
+ AnyAccount<P, R> & AccountOfProfileAndRoot,
53
+ never
54
+ >[Schema.TypeId];
55
+ static pipe() {
56
+ // eslint-disable-next-line prefer-rest-params
57
+ return pipeArguments(this, arguments);
58
+ }
59
+ static type = "Account" as const;
60
+ static [controlledAccountSym]: AccountOfProfileAndRoot &
61
+ ControlledAccount<P, R>;
62
+
63
+ id!: ID<this>;
64
+ _type!: "Account";
65
+ _owner!: AnyAccount | AnyGroup;
66
+ _refs!: AnyAccount<P, R>["_refs"];
67
+ _raw!: RawAccount | RawControlledAccount;
68
+ _loadedAs!: ControlledAccount;
69
+ _schema!: typeof AccountOfProfileAndRoot;
70
+
71
+ isMe: boolean;
72
+ sessionID?: SessionID;
73
+
74
+ constructor(
75
+ init: undefined,
76
+ options: { owner: ControlledAccount | AnyGroup | AnyAccount }
77
+ );
78
+ constructor(
79
+ init: undefined,
80
+ options: { fromRaw: RawAccount | RawControlledAccount }
81
+ );
82
+ constructor(
83
+ init: undefined,
84
+ options:
85
+ | { fromRaw: RawAccount | RawControlledAccount }
86
+ | { owner: ControlledAccount | AnyGroup | AnyAccount }
87
+ ) {
88
+ super();
89
+ if (!("fromRaw" in options)) {
90
+ throw new Error(
91
+ "Can only construct account from raw or with .create()"
92
+ );
93
+ }
94
+ this.isMe =
95
+ options.fromRaw.id == options.fromRaw.core.node.account.id;
96
+
97
+ const refs = {
98
+ get profile() {
99
+ const profileID = options.fromRaw.get("profile");
100
+ return profileID && new ValueRef(
101
+ profileID as unknown as ID<Schema.Schema.To<P>>,
102
+ controlledAccountFromNode(options.fromRaw.core.node),
103
+ fields.profile
104
+ );
105
+ },
106
+ get root() {
107
+ const rootID = options.fromRaw.get("root");
108
+ return rootID && new ValueRef(
109
+ rootID as unknown as ID<Schema.Schema.To<P>>,
110
+ controlledAccountFromNode(options.fromRaw.core.node),
111
+ fields.root
112
+ );
113
+ },
114
+ };
115
+
116
+ Object.defineProperties(this, {
117
+ id: { value: options.fromRaw.id, enumerable: false },
118
+ _type: { value: "Account", enumerable: false },
119
+ _owner: { value: this, enumerable: false },
120
+ _refs: { value: refs, enumerable: false },
121
+ _raw: { value: options.fromRaw, enumerable: false },
122
+ _loadedAs: {
123
+ get: () =>
124
+ this.isMe
125
+ ? this
126
+ : controlledAccountFromNode(
127
+ options.fromRaw.core.node
128
+ ),
129
+ enumerable: false,
130
+ },
131
+ _schema: { value: AccountOfProfileAndRoot, enumerable: false },
132
+ });
133
+
134
+ if (this.isMe) {
135
+ (this as ControlledAccount).sessionID =
136
+ options.fromRaw.core.node.currentSessionID;
137
+ }
138
+ }
139
+
140
+ static fromRaw(raw: RawAccount | RawControlledAccount) {
141
+ return new AccountOfProfileAndRoot(undefined, {
142
+ fromRaw: raw,
143
+ });
144
+ }
145
+
146
+ static async create(options: {
147
+ name: string;
148
+ migration?: AccountMigration<AccountSchema<AnyAccount<P, R>, P, R>>;
149
+ initialAgentSecret?: AgentSecret;
150
+ peersToLoadFrom?: Peer[];
151
+ }): Promise<AccountOfProfileAndRoot & ControlledAccount<P, R>> {
152
+ const { node } = await LocalNode.withNewlyCreatedAccount({
153
+ ...options,
154
+ migration:
155
+ options.migration &&
156
+ (async (rawAccount) => {
157
+ const account = new AccountOfProfileAndRoot(undefined, {
158
+ fromRaw: rawAccount,
159
+ }) as AccountOfProfileAndRoot & ControlledAccount<P, R>;
160
+
161
+ await options.migration!(account);
162
+ }),
163
+ });
164
+
165
+ return new AccountOfProfileAndRoot(undefined, {
166
+ fromRaw: node.account as RawControlledAccount,
167
+ }) as AccountOfProfileAndRoot & ControlledAccount<P, R>;
168
+ }
169
+
170
+ static async become(options: {
171
+ accountID: ID<AnyAccount<P, R>>;
172
+ accountSecret: AgentSecret;
173
+ sessionID: SessionID;
174
+ peersToLoadFrom: Peer[];
175
+ migration?: AccountMigration<AccountSchema<AnyAccount<P, R>, P, R>>;
176
+ }): Promise<AccountOfProfileAndRoot & ControlledAccount<P, R>> {
177
+ const node = await LocalNode.withLoadedAccount({
178
+ accountID: options.accountID as unknown as CoID<RawAccount>,
179
+ accountSecret: options.accountSecret,
180
+ sessionID: options.sessionID,
181
+ peersToLoadFrom: options.peersToLoadFrom,
182
+ migration:
183
+ options.migration &&
184
+ (async (rawAccount) => {
185
+ const account = new AccountOfProfileAndRoot(undefined, {
186
+ fromRaw: rawAccount,
187
+ }) as AccountOfProfileAndRoot & ControlledAccount<P, R>;
188
+
189
+ await options.migration!(account);
190
+ }),
191
+ });
192
+
193
+ return new AccountOfProfileAndRoot(undefined, {
194
+ fromRaw: node.account as RawControlledAccount,
195
+ }) as AccountOfProfileAndRoot & ControlledAccount<P, R>;
196
+ }
197
+
198
+ async acceptInvite<V extends CoValue>(
199
+ valueID: ID<V>,
200
+ inviteSecret: InviteSecret,
201
+ valueSchema: CoValueSchema<V, V>
202
+ ): Promise<V | undefined> {
203
+ if (!this.isMe) {
204
+ throw new Error("Only a controlled account can accept invites");
205
+ }
206
+
207
+ await (this._raw as RawControlledAccount).acceptInvite(
208
+ valueID as unknown as CoID<RawCoValue>,
209
+ inviteSecret
210
+ );
211
+
212
+ return valueSchema.load(valueID, { as: this as ControlledAccount });
213
+ }
214
+
215
+ get profile(): S.Schema.To<P> | undefined {
216
+ return this._refs.profile.accessFrom(this);
217
+ }
218
+
219
+ get root(): S.Schema.To<R> | undefined {
220
+ return this._refs.root.accessFrom(this);
221
+ }
222
+
223
+ myRole(): "admin" {
224
+ return "admin";
225
+ }
226
+
227
+ toJSON() {
228
+ return {
229
+ profile: this.profile?.toJSON(),
230
+ root: this.root?.toJSON(),
231
+ };
232
+ }
233
+
234
+ [inspect]() {
235
+ return this.toJSON();
236
+ }
237
+
238
+ static as<SubClass>() {
239
+ return this as unknown as AccountSchema<SubClass, P, R>;
240
+ }
241
+ }
242
+
243
+ return AccountOfProfileAndRoot as AccountSchema<
244
+ AccountOfProfileAndRoot & AnyAccount<P, R>,
245
+ P,
246
+ R
247
+ > & {
248
+ as<SubClass>(): AccountSchema<SubClass, P, R>;
249
+ };
250
+ }
251
+
252
+ export class BaseProfile extends CoMapOf({
253
+ name: S.string,
254
+ }).as<BaseProfile>() {}
255
+
256
+ export class Account extends AccountOf<
257
+ typeof BaseProfile,
258
+ Schema.Schema<null>
259
+ >({
260
+ profile: BaseProfile,
261
+ root: S.null,
262
+ }).as<Account>() {}
263
+
264
+ const simpleControlledAccounts = new WeakMap<
265
+ RawControlledAccount,
266
+ Account & ControlledAccount
267
+ >();
268
+
269
+ export function controlledAccountFromNode(node: LocalNode): ControlledAccount {
270
+ if (!(node.account instanceof RawControlledAccount)) {
271
+ throw new Error("Expected a controlled account");
272
+ }
273
+ let simpleAccount;
274
+
275
+ if (simpleControlledAccounts.has(node.account)) {
276
+ simpleAccount = simpleControlledAccounts.get(node.account);
277
+ } else {
278
+ simpleAccount = Account.fromRaw(node.account) as Account &
279
+ ControlledAccount;
280
+ simpleControlledAccounts.set(node.account, simpleAccount);
281
+ }
282
+
283
+ return simpleAccount!;
284
+ }
@@ -0,0 +1,12 @@
1
+ import { AccountSchema, controlledAccountSym } from "./account.js";
2
+
3
+ export type AccountMigration<A extends AccountSchema> = (
4
+ me: A[controlledAccountSym]
5
+ ) => void | Promise<void>;
6
+
7
+ export function createAccountMigration<A extends AccountSchema>(
8
+ accountSchema: A,
9
+ migration: AccountMigration<A>
10
+ ): AccountMigration<A> {
11
+ return migration;
12
+ }
@@ -0,0 +1,57 @@
1
+ import { JsonValue, RawCoList, CojsonInternalTypes } from "cojson";
2
+ import { SchemaWithOutput } from "../../schemaHelpers.js";
3
+ import { CoValue, CoValueSchema } from "../../coValueInterfaces.js";
4
+ import { Schema } from "@effect/schema";
5
+ import { ValueRef } from "../../refs.js";
6
+ import { AnyAccount } from "../account/account.js";
7
+
8
+ /**
9
+ * @category Schemas & CoValues - CoList
10
+ */
11
+ export interface CoListBase<
12
+ Item extends CoValueSchema | SchemaWithOutput<JsonValue>,
13
+ > extends CoValue<"CoList", RawCoList> {
14
+ /** @category Collaboration metadata */
15
+ readonly _refs: {
16
+ [idx: number]: ValueRef<Schema.Schema.To<Item>>;
17
+ length: number;
18
+ [Symbol.iterator]: () => IterableIterator<
19
+ ValueRef<Schema.Schema.To<Item>>
20
+ >;
21
+ };
22
+ readonly _edits: {
23
+ [idx: number]: {
24
+ value?: Schema.Schema.To<Item>;
25
+ ref?: Item extends CoValueSchema
26
+ ? ValueRef<Schema.Schema.To<Item>>
27
+ : never;
28
+ by?: AnyAccount;
29
+ madeAt: Date;
30
+ tx: CojsonInternalTypes.TransactionID;
31
+ };
32
+ };
33
+ }
34
+
35
+ /**
36
+ * @category Schemas & CoValues - CoList
37
+ */
38
+ export type CoList<Item extends CoValueSchema | SchemaWithOutput<JsonValue>> =
39
+ Array<
40
+ Item extends CoValueSchema
41
+ ? Schema.Schema.To<Item> | undefined
42
+ : Schema.Schema.To<Item>
43
+ > &
44
+ CoListBase<Item>;
45
+
46
+ /**
47
+ * @category Schemas & CoValues - CoList
48
+ */
49
+ export interface CoListSchema<
50
+ Self,
51
+ Item extends CoValueSchema | SchemaWithOutput<JsonValue>,
52
+ > extends CoValueSchema<
53
+ Self,
54
+ CoList<Item>,
55
+ "CoList",
56
+ Schema.Schema.To<Item>[]
57
+ > {}