jazz-tools 0.7.0-alpha.9 → 0.7.1
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.
- package/.eslintrc.cjs +3 -10
- package/.prettierrc.js +9 -0
- package/.turbo/turbo-build.log +3 -19
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +140 -0
- package/CHANGELOG.md +298 -0
- package/README.md +10 -2
- package/dist/coValues/account.js +59 -41
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.js +49 -46
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.js +143 -44
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.js +144 -35
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/deepLoading.js +60 -0
- package/dist/coValues/deepLoading.js.map +1 -0
- package/dist/coValues/extensions/imageDef.js +10 -7
- package/dist/coValues/extensions/imageDef.js.map +1 -1
- package/dist/coValues/group.js +49 -13
- package/dist/coValues/group.js.map +1 -1
- package/dist/coValues/interfaces.js +70 -31
- package/dist/coValues/interfaces.js.map +1 -1
- package/dist/implementation/devtoolsFormatters.js +114 -0
- package/dist/implementation/devtoolsFormatters.js.map +1 -0
- package/dist/implementation/refs.js +58 -18
- package/dist/implementation/refs.js.map +1 -1
- package/dist/implementation/schema.js +58 -0
- package/dist/implementation/schema.js.map +1 -0
- package/dist/implementation/subscriptionScope.js +19 -1
- package/dist/implementation/subscriptionScope.js.map +1 -1
- package/dist/implementation/symbols.js +5 -0
- package/dist/implementation/symbols.js.map +1 -0
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.js +5 -2
- package/dist/internal.js.map +1 -1
- package/dist/tests/coList.test.js +51 -48
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +131 -74
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coStream.test.js +56 -41
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/deepLoading.test.js +188 -0
- package/dist/tests/deepLoading.test.js.map +1 -0
- package/dist/tests/groupsAndAccounts.test.js +83 -0
- package/dist/tests/groupsAndAccounts.test.js.map +1 -0
- package/package.json +17 -9
- package/src/coValues/account.ts +113 -125
- package/src/coValues/coList.ts +87 -103
- package/src/coValues/coMap.ts +200 -147
- package/src/coValues/coStream.ts +264 -80
- package/src/coValues/deepLoading.ts +229 -0
- package/src/coValues/extensions/imageDef.ts +17 -13
- package/src/coValues/group.ts +92 -58
- package/src/coValues/interfaces.ts +215 -115
- package/src/implementation/devtoolsFormatters.ts +110 -0
- package/src/implementation/inspect.ts +1 -1
- package/src/implementation/refs.ts +80 -28
- package/src/implementation/schema.ts +138 -0
- package/src/implementation/subscriptionScope.ts +48 -12
- package/src/implementation/symbols.ts +11 -0
- package/src/index.ts +12 -8
- package/src/internal.ts +7 -3
- package/src/tests/coList.test.ts +77 -62
- package/src/tests/coMap.test.ts +201 -114
- package/src/tests/coStream.test.ts +113 -84
- package/src/tests/deepLoading.test.ts +301 -0
- package/src/tests/groupsAndAccounts.test.ts +91 -0
- package/dist/implementation/encoding.js +0 -26
- package/dist/implementation/encoding.js.map +0 -1
- package/src/implementation/encoding.ts +0 -105
@@ -0,0 +1,301 @@
|
|
1
|
+
const Crypto = await WasmCrypto.create();
|
2
|
+
import { expect, describe, test, expectTypeOf } from "vitest";
|
3
|
+
import { connectedPeers } from "cojson/src/streamUtils.js";
|
4
|
+
import {
|
5
|
+
Account,
|
6
|
+
CoList,
|
7
|
+
CoMap,
|
8
|
+
CoStream,
|
9
|
+
SessionID,
|
10
|
+
WasmCrypto,
|
11
|
+
co,
|
12
|
+
Profile,
|
13
|
+
isControlledAccount,
|
14
|
+
ID,
|
15
|
+
} from "../index.js";
|
16
|
+
import { newRandomSessionID } from "cojson/src/coValueCore.js";
|
17
|
+
|
18
|
+
class TestMap extends CoMap {
|
19
|
+
list = co.ref(TestList);
|
20
|
+
optionalRef = co.ref(InnermostMap, { optional: true });
|
21
|
+
}
|
22
|
+
|
23
|
+
class TestList extends CoList.Of(co.ref(() => InnerMap)) {}
|
24
|
+
|
25
|
+
class InnerMap extends CoMap {
|
26
|
+
stream = co.ref(TestStream);
|
27
|
+
}
|
28
|
+
|
29
|
+
class TestStream extends CoStream.Of(co.ref(() => InnermostMap)) {}
|
30
|
+
|
31
|
+
class InnermostMap extends CoMap {
|
32
|
+
value = co.string;
|
33
|
+
}
|
34
|
+
|
35
|
+
describe("Deep loading with depth arg", async () => {
|
36
|
+
const me = await Account.create({
|
37
|
+
creationProps: { name: "Hermes Puggington" },
|
38
|
+
crypto: Crypto,
|
39
|
+
});
|
40
|
+
|
41
|
+
const [initialAsPeer, secondPeer] = connectedPeers("initial", "second", {
|
42
|
+
peer1role: "server",
|
43
|
+
peer2role: "client",
|
44
|
+
});
|
45
|
+
if (!isControlledAccount(me)) {
|
46
|
+
throw "me is not a controlled account";
|
47
|
+
}
|
48
|
+
me._raw.core.node.syncManager.addPeer(secondPeer);
|
49
|
+
const meOnSecondPeer = await Account.become({
|
50
|
+
accountID: me.id,
|
51
|
+
accountSecret: me._raw.agentSecret,
|
52
|
+
peersToLoadFrom: [initialAsPeer],
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
54
|
+
sessionID: newRandomSessionID(me.id as any),
|
55
|
+
crypto: Crypto,
|
56
|
+
});
|
57
|
+
|
58
|
+
test("loading a deeply nested object will wait until all required refs are loaded", async () => {
|
59
|
+
const map = TestMap.create(
|
60
|
+
{
|
61
|
+
list: TestList.create(
|
62
|
+
[
|
63
|
+
InnerMap.create(
|
64
|
+
{
|
65
|
+
stream: TestStream.create(
|
66
|
+
[
|
67
|
+
InnermostMap.create(
|
68
|
+
{ value: "hello" },
|
69
|
+
{ owner: me },
|
70
|
+
),
|
71
|
+
],
|
72
|
+
{ owner: me },
|
73
|
+
),
|
74
|
+
},
|
75
|
+
{ owner: me },
|
76
|
+
),
|
77
|
+
],
|
78
|
+
{ owner: me },
|
79
|
+
),
|
80
|
+
},
|
81
|
+
{ owner: me },
|
82
|
+
);
|
83
|
+
|
84
|
+
const map1 = await TestMap.load(map.id, meOnSecondPeer, {});
|
85
|
+
expectTypeOf(map1).toEqualTypeOf<TestMap | undefined>();
|
86
|
+
if (map1 === undefined) {
|
87
|
+
throw new Error("map1 is undefined");
|
88
|
+
}
|
89
|
+
expect(map1.list).toBe(null);
|
90
|
+
|
91
|
+
const map2 = await TestMap.load(map.id, meOnSecondPeer, { list: [] });
|
92
|
+
expectTypeOf(map2).toEqualTypeOf<
|
93
|
+
| (TestMap & {
|
94
|
+
list: TestList;
|
95
|
+
})
|
96
|
+
| undefined
|
97
|
+
>();
|
98
|
+
if (map2 === undefined) {
|
99
|
+
throw new Error("map2 is undefined");
|
100
|
+
}
|
101
|
+
expect(map2.list).not.toBe(null);
|
102
|
+
expect(map2.list[0]).toBe(null);
|
103
|
+
|
104
|
+
const map3 = await TestMap.load(map.id, meOnSecondPeer, { list: [{}] });
|
105
|
+
expectTypeOf(map3).toEqualTypeOf<
|
106
|
+
| (TestMap & {
|
107
|
+
list: TestList & InnerMap[];
|
108
|
+
})
|
109
|
+
| undefined
|
110
|
+
>();
|
111
|
+
if (map3 === undefined) {
|
112
|
+
throw new Error("map3 is undefined");
|
113
|
+
}
|
114
|
+
expect(map3.list[0]).not.toBe(null);
|
115
|
+
expect(map3.list[0]?.stream).toBe(null);
|
116
|
+
|
117
|
+
const map3a = await TestMap.load(map.id, meOnSecondPeer, {
|
118
|
+
optionalRef: {},
|
119
|
+
});
|
120
|
+
expectTypeOf(map3a).toEqualTypeOf<
|
121
|
+
| (TestMap & {
|
122
|
+
optionalRef: InnermostMap | undefined;
|
123
|
+
})
|
124
|
+
| undefined
|
125
|
+
>();
|
126
|
+
|
127
|
+
const map4 = await TestMap.load(map.id, meOnSecondPeer, {
|
128
|
+
list: [{ stream: [] }],
|
129
|
+
});
|
130
|
+
expectTypeOf(map4).toEqualTypeOf<
|
131
|
+
| (TestMap & {
|
132
|
+
list: TestList & (InnerMap & { stream: TestStream })[];
|
133
|
+
})
|
134
|
+
| undefined
|
135
|
+
>();
|
136
|
+
if (map4 === undefined) {
|
137
|
+
throw new Error("map4 is undefined");
|
138
|
+
}
|
139
|
+
expect(map4.list[0]?.stream).not.toBe(null);
|
140
|
+
// TODO: we should expect null here, but apparently we don't even have the id/ref?
|
141
|
+
expect(map4.list[0]?.stream?.[me.id]?.value).not.toBeDefined();
|
142
|
+
expect(map4.list[0]?.stream?.byMe?.value).not.toBeDefined();
|
143
|
+
|
144
|
+
const map5 = await TestMap.load(map.id, meOnSecondPeer, {
|
145
|
+
list: [{ stream: [{}] }],
|
146
|
+
});
|
147
|
+
type ExpectedMap5 =
|
148
|
+
| (TestMap & {
|
149
|
+
list: TestList &
|
150
|
+
(InnerMap & {
|
151
|
+
stream: TestStream & {
|
152
|
+
byMe?: { value: InnermostMap };
|
153
|
+
inCurrentSession?: { value: InnermostMap };
|
154
|
+
perSession: {
|
155
|
+
[sessionID: SessionID]: {
|
156
|
+
value: InnermostMap;
|
157
|
+
};
|
158
|
+
};
|
159
|
+
} & {
|
160
|
+
[key: ID<Account>]: { value: InnermostMap };
|
161
|
+
};
|
162
|
+
})[];
|
163
|
+
})
|
164
|
+
| undefined;
|
165
|
+
|
166
|
+
expectTypeOf(map5).toEqualTypeOf<ExpectedMap5>();
|
167
|
+
if (map5 === undefined) {
|
168
|
+
throw new Error("map5 is undefined");
|
169
|
+
}
|
170
|
+
expect(map5.list[0]?.stream?.[me.id]?.value).not.toBe(null);
|
171
|
+
expect(map5.list[0]?.stream?.byMe?.value).not.toBe(null);
|
172
|
+
});
|
173
|
+
});
|
174
|
+
|
175
|
+
class CustomProfile extends Profile {
|
176
|
+
stream = co.ref(TestStream);
|
177
|
+
}
|
178
|
+
|
179
|
+
class CustomAccount extends Account {
|
180
|
+
profile = co.ref(CustomProfile);
|
181
|
+
root = co.ref(TestMap);
|
182
|
+
|
183
|
+
async migrate(creationProps?: { name: string } | undefined) {
|
184
|
+
if (creationProps) {
|
185
|
+
this.profile = CustomProfile.create(
|
186
|
+
{
|
187
|
+
name: creationProps.name,
|
188
|
+
stream: TestStream.create([], { owner: this }),
|
189
|
+
},
|
190
|
+
{ owner: this },
|
191
|
+
);
|
192
|
+
this.root = TestMap.create(
|
193
|
+
{ list: TestList.create([], { owner: this }) },
|
194
|
+
{ owner: this },
|
195
|
+
);
|
196
|
+
}
|
197
|
+
|
198
|
+
const thisLoaded = await CustomAccount.load(this, {
|
199
|
+
profile: { stream: [] },
|
200
|
+
root: { list: [] },
|
201
|
+
});
|
202
|
+
expectTypeOf(thisLoaded).toEqualTypeOf<
|
203
|
+
| (CustomAccount & {
|
204
|
+
profile: CustomProfile & {
|
205
|
+
stream: TestStream;
|
206
|
+
};
|
207
|
+
root: TestMap & {
|
208
|
+
list: TestList;
|
209
|
+
};
|
210
|
+
})
|
211
|
+
| undefined
|
212
|
+
>();
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
test("Deep loading within account", async () => {
|
217
|
+
const me = await CustomAccount.create({
|
218
|
+
creationProps: { name: "Hermes Puggington" },
|
219
|
+
crypto: Crypto,
|
220
|
+
});
|
221
|
+
|
222
|
+
const meLoaded = await CustomAccount.load(me, {
|
223
|
+
profile: { stream: [] },
|
224
|
+
root: { list: [] },
|
225
|
+
});
|
226
|
+
expectTypeOf(meLoaded).toEqualTypeOf<
|
227
|
+
| (CustomAccount & {
|
228
|
+
profile: CustomProfile & {
|
229
|
+
stream: TestStream;
|
230
|
+
};
|
231
|
+
root: TestMap & {
|
232
|
+
list: TestList;
|
233
|
+
};
|
234
|
+
})
|
235
|
+
| undefined
|
236
|
+
>();
|
237
|
+
if (meLoaded === undefined) {
|
238
|
+
throw new Error("meLoaded is undefined");
|
239
|
+
}
|
240
|
+
expect(meLoaded.profile.stream).not.toBe(null);
|
241
|
+
expect(meLoaded.root.list).not.toBe(null);
|
242
|
+
});
|
243
|
+
|
244
|
+
class RecordLike extends CoMap.Record(co.ref(TestMap)) {}
|
245
|
+
|
246
|
+
test("Deep loading a record-like coMap", async () => {
|
247
|
+
const me = await Account.create({
|
248
|
+
creationProps: { name: "Hermes Puggington" },
|
249
|
+
crypto: Crypto,
|
250
|
+
});
|
251
|
+
|
252
|
+
const [initialAsPeer, secondPeer] = connectedPeers("initial", "second", {
|
253
|
+
peer1role: "server",
|
254
|
+
peer2role: "client",
|
255
|
+
});
|
256
|
+
if (!isControlledAccount(me)) {
|
257
|
+
throw "me is not a controlled account";
|
258
|
+
}
|
259
|
+
me._raw.core.node.syncManager.addPeer(secondPeer);
|
260
|
+
const meOnSecondPeer = await Account.become({
|
261
|
+
accountID: me.id,
|
262
|
+
accountSecret: me._raw.agentSecret,
|
263
|
+
peersToLoadFrom: [initialAsPeer],
|
264
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
265
|
+
sessionID: newRandomSessionID(me.id as any),
|
266
|
+
crypto: Crypto,
|
267
|
+
});
|
268
|
+
|
269
|
+
const record = RecordLike.create(
|
270
|
+
{
|
271
|
+
key1: TestMap.create(
|
272
|
+
{ list: TestList.create([], { owner: me }) },
|
273
|
+
{ owner: me },
|
274
|
+
),
|
275
|
+
key2: TestMap.create(
|
276
|
+
{ list: TestList.create([], { owner: me }) },
|
277
|
+
{ owner: me },
|
278
|
+
),
|
279
|
+
},
|
280
|
+
{ owner: me },
|
281
|
+
);
|
282
|
+
|
283
|
+
const recordLoaded = await RecordLike.load(record.id, meOnSecondPeer, [
|
284
|
+
{ list: [{}] },
|
285
|
+
]);
|
286
|
+
expectTypeOf(recordLoaded).toEqualTypeOf<
|
287
|
+
| (RecordLike & {
|
288
|
+
[key: string]: TestMap & {
|
289
|
+
list: TestList & InnerMap[];
|
290
|
+
};
|
291
|
+
})
|
292
|
+
| undefined
|
293
|
+
>();
|
294
|
+
if (recordLoaded === undefined) {
|
295
|
+
throw new Error("recordLoaded is undefined");
|
296
|
+
}
|
297
|
+
expect(recordLoaded.key1?.list).not.toBe(null);
|
298
|
+
expect(recordLoaded.key1?.list).not.toBe(undefined);
|
299
|
+
expect(recordLoaded.key2?.list).not.toBe(null);
|
300
|
+
expect(recordLoaded.key2?.list).not.toBe(undefined);
|
301
|
+
});
|
@@ -0,0 +1,91 @@
|
|
1
|
+
import { expect, describe, test } from "vitest";
|
2
|
+
import { Account, CoMap, co, Group, WasmCrypto } from "../index.js";
|
3
|
+
|
4
|
+
const Crypto = await WasmCrypto.create();
|
5
|
+
|
6
|
+
describe("Custom accounts and groups", async () => {
|
7
|
+
class CustomProfile extends CoMap {
|
8
|
+
name = co.string;
|
9
|
+
color = co.string;
|
10
|
+
}
|
11
|
+
|
12
|
+
class CustomAccount extends Account {
|
13
|
+
profile = co.ref(CustomProfile);
|
14
|
+
root = co.ref(CoMap);
|
15
|
+
|
16
|
+
migrate(creationProps?: { name: string }) {
|
17
|
+
if (creationProps) {
|
18
|
+
const profileGroup = Group.create({ owner: this });
|
19
|
+
profileGroup.addMember("everyone", "reader");
|
20
|
+
this.profile = CustomProfile.create(
|
21
|
+
{ name: creationProps.name, color: "blue" },
|
22
|
+
{ owner: this },
|
23
|
+
);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
class CustomGroup extends Group {
|
29
|
+
profile = co.null;
|
30
|
+
root = co.null;
|
31
|
+
[co.members] = co.ref(CustomAccount);
|
32
|
+
|
33
|
+
get nMembers() {
|
34
|
+
return this.members.length;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
test("Custom account and group", async () => {
|
39
|
+
const me = await CustomAccount.create({
|
40
|
+
creationProps: { name: "Hermes Puggington" },
|
41
|
+
crypto: Crypto,
|
42
|
+
});
|
43
|
+
|
44
|
+
expect(me.profile).toBeDefined();
|
45
|
+
expect(me.profile?.name).toBe("Hermes Puggington");
|
46
|
+
expect(me.profile?.color).toBe("blue");
|
47
|
+
|
48
|
+
const group = new CustomGroup({ owner: me });
|
49
|
+
group.addMember("everyone", "reader");
|
50
|
+
|
51
|
+
expect(group.members).toMatchObject([
|
52
|
+
{ id: me.id, role: "admin" },
|
53
|
+
{ id: "everyone", role: "reader" },
|
54
|
+
]);
|
55
|
+
|
56
|
+
expect(group.nMembers).toBe(2);
|
57
|
+
|
58
|
+
await new Promise<void>((resolve) => {
|
59
|
+
CustomGroup.subscribe(group, {}, (update) => {
|
60
|
+
const meAsMember = update.members.find((member) => {
|
61
|
+
return member.id === me.id && member.account?.profile;
|
62
|
+
});
|
63
|
+
if (meAsMember) {
|
64
|
+
expect(meAsMember.account?.profile?.name).toBe(
|
65
|
+
"Hermes Puggington",
|
66
|
+
);
|
67
|
+
expect(meAsMember.account?.profile?.color).toBe("blue");
|
68
|
+
resolve();
|
69
|
+
}
|
70
|
+
});
|
71
|
+
});
|
72
|
+
|
73
|
+
class MyMap extends CoMap {
|
74
|
+
name = co.string;
|
75
|
+
}
|
76
|
+
|
77
|
+
const map = MyMap.create({ name: "test" }, { owner: group });
|
78
|
+
|
79
|
+
const meAsCastMember = map._owner
|
80
|
+
.as(CustomGroup)
|
81
|
+
.members.find((member) => member.id === me.id);
|
82
|
+
expect(meAsCastMember?.account?.profile?.name).toBe(
|
83
|
+
"Hermes Puggington",
|
84
|
+
);
|
85
|
+
expect(meAsCastMember?.account?.profile?.color).toBe("blue");
|
86
|
+
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
88
|
+
expect((map._owner as any).nMembers).toBeUndefined();
|
89
|
+
expect(map._owner.as(CustomGroup).nMembers).toBe(2);
|
90
|
+
});
|
91
|
+
});
|
@@ -1,26 +0,0 @@
|
|
1
|
-
export const SchemaInit = Symbol.for("SchemaInit");
|
2
|
-
export const InitValues = Symbol.for("InitValues");
|
3
|
-
export const ItemsSym = Symbol.for("items");
|
4
|
-
export const val = {
|
5
|
-
string: { [SchemaInit]: "json" },
|
6
|
-
number: { [SchemaInit]: "json" },
|
7
|
-
boolean: { [SchemaInit]: "json" },
|
8
|
-
literal: (_lit) => {
|
9
|
-
return { [SchemaInit]: "json" };
|
10
|
-
},
|
11
|
-
json: () => {
|
12
|
-
return { [SchemaInit]: "json" };
|
13
|
-
},
|
14
|
-
encoded: (arg) => {
|
15
|
-
return { [SchemaInit]: { encoded: arg } };
|
16
|
-
},
|
17
|
-
ref: (arg) => {
|
18
|
-
return { [SchemaInit]: { ref: arg } };
|
19
|
-
},
|
20
|
-
items: ItemsSym,
|
21
|
-
};
|
22
|
-
import { Date } from "@effect/schema/Schema";
|
23
|
-
export const Encoders = {
|
24
|
-
Date,
|
25
|
-
};
|
26
|
-
//# sourceMappingURL=encoding.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/implementation/encoding.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAGnD,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAGnD,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAG5C,MAAM,CAAC,MAAM,GAAG,GAAG;IACf,MAAM,EAAE,EAAC,CAAC,UAAU,CAAC,EAAE,MAAyB,EAA4B;IAC5E,MAAM,EAAE,EAAC,CAAC,UAAU,CAAC,EAAE,MAAyB,EAA4B;IAC5E,OAAO,EAAE,EAAC,CAAC,UAAU,CAAC,EAAE,MAAyB,EAA6B;IAC9E,OAAO,EAAE,CACL,IAAO,EACD,EAAE;QACR,OAAO,EAAC,CAAC,UAAU,CAAC,EAAE,MAAyB,EAAS,CAAC;IAC7D,CAAC;IACD,IAAI,EAAE,GAAgC,EAAE;QACpC,OAAO,EAAC,CAAC,UAAU,CAAC,EAAE,MAAyB,EAAS,CAAC;IAC7D,CAAC;IACD,OAAO,EAAE,CAAI,GAAe,EAAU,EAAE;QACpC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAqB,EAAS,CAAC;IACxE,CAAC;IACD,GAAG,EAAE,CACD,GAAyC,EACd,EAAE;QAC7B,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAqB,EAAS,CAAC;IACpE,CAAC;IACD,KAAK,EAAE,QAAoB;CAC9B,CAAA;AA6BD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,MAAM,CAAC,MAAM,QAAQ,GAAG;IACpB,IAAI;CACP,CAAC"}
|
@@ -1,105 +0,0 @@
|
|
1
|
-
import type { JsonValue, RawCoValue } from "cojson";
|
2
|
-
import type { CoValue, CoValueClass } from "../internal.js";
|
3
|
-
import type { Schema, TypeId } from "@effect/schema/Schema";
|
4
|
-
|
5
|
-
export type ValMarker = { readonly __field: unique symbol };
|
6
|
-
export type val<T> = T | (T & ValMarker);
|
7
|
-
export type IsVal<C, R> = C extends infer _A | infer B
|
8
|
-
? B extends ValMarker
|
9
|
-
? R
|
10
|
-
: never
|
11
|
-
: never;
|
12
|
-
|
13
|
-
export const SchemaInit = Symbol.for("SchemaInit");
|
14
|
-
export type SchemaInit = typeof SchemaInit;
|
15
|
-
|
16
|
-
export const InitValues = Symbol.for("InitValues");
|
17
|
-
export type InitValues = typeof InitValues;
|
18
|
-
|
19
|
-
export const ItemsSym = Symbol.for("items");
|
20
|
-
export type ItemsSym = typeof ItemsSym;
|
21
|
-
|
22
|
-
export const val = {
|
23
|
-
string: {[SchemaInit]: "json" satisfies Encoding } as unknown as val<string>,
|
24
|
-
number: {[SchemaInit]: "json" satisfies Encoding } as unknown as val<number>,
|
25
|
-
boolean: {[SchemaInit]: "json" satisfies Encoding } as unknown as val<boolean>,
|
26
|
-
literal: <T extends string | number | boolean>(
|
27
|
-
_lit: T
|
28
|
-
): val<T> => {
|
29
|
-
return {[SchemaInit]: "json" satisfies Encoding } as any;
|
30
|
-
},
|
31
|
-
json: <T extends JsonValue>(): val<T> => {
|
32
|
-
return {[SchemaInit]: "json" satisfies Encoding } as any;
|
33
|
-
},
|
34
|
-
encoded: <T>(arg: Encoder<T>): val<T> => {
|
35
|
-
return { [SchemaInit]: { encoded: arg } satisfies Encoding } as any;
|
36
|
-
},
|
37
|
-
ref: <C extends CoValueClass>(
|
38
|
-
arg: (_raw: InstanceType<C>['_raw']) => C
|
39
|
-
): val<InstanceType<C> | null> => {
|
40
|
-
return { [SchemaInit]: { ref: arg } satisfies Encoding } as any;
|
41
|
-
},
|
42
|
-
items: ItemsSym as ItemsSym,
|
43
|
-
}
|
44
|
-
|
45
|
-
export type JsonEncoded = "json";
|
46
|
-
export type EncodedAs<V> = { encoded: Encoder<V> };
|
47
|
-
export type RefEncoded<V extends CoValue> = {
|
48
|
-
ref: (raw: RawCoValue) => CoValueClass<V>;
|
49
|
-
};
|
50
|
-
|
51
|
-
export type Encoding = JsonEncoded | RefEncoded<CoValue> | EncodedAs<any>;
|
52
|
-
|
53
|
-
export type EncodingFor<Field> = NonNullable<Field> extends CoValue
|
54
|
-
? RefEncoded<NonNullable<Field>>
|
55
|
-
: NonNullable<Field> extends JsonValue
|
56
|
-
? JsonEncoded
|
57
|
-
: EncodedAs<NonNullable<Field>>;
|
58
|
-
|
59
|
-
export type EffectSchemaWithInputAndOutput<A, I = A> = Schema<
|
60
|
-
any,
|
61
|
-
any,
|
62
|
-
never
|
63
|
-
> & {
|
64
|
-
[TypeId]: {
|
65
|
-
_A: (_: any) => A;
|
66
|
-
_I: (_: any) => I;
|
67
|
-
};
|
68
|
-
};
|
69
|
-
|
70
|
-
export type Encoder<V> = EffectSchemaWithInputAndOutput<V, JsonValue>;
|
71
|
-
|
72
|
-
import { Date } from "@effect/schema/Schema";
|
73
|
-
|
74
|
-
export const Encoders = {
|
75
|
-
Date,
|
76
|
-
};
|
77
|
-
|
78
|
-
export type EnsureCoValueNullable<
|
79
|
-
V,
|
80
|
-
Key extends string | ItemsSym,
|
81
|
-
> = NonNullable<V> extends CoValue
|
82
|
-
? null extends V
|
83
|
-
? V
|
84
|
-
: Key extends string
|
85
|
-
? [
|
86
|
-
`👋 CoMap fields that are CoValue references should be nullable, declare ${Key} as:`,
|
87
|
-
V | null,
|
88
|
-
]
|
89
|
-
: [
|
90
|
-
`👋 CoMap fields that are CoValue references should be nullable, declare _item as:`,
|
91
|
-
V | null,
|
92
|
-
]
|
93
|
-
: V;
|
94
|
-
|
95
|
-
export type ValidItem<
|
96
|
-
Item,
|
97
|
-
ContainerType extends string,
|
98
|
-
> = NonNullable<Item> extends CoValue
|
99
|
-
? null extends Item
|
100
|
-
? any
|
101
|
-
: [
|
102
|
-
`👋 CoList items that are CoValue references should be nullable, make sure the Item generic parameter of ${ContainerType} is:`,
|
103
|
-
Item | null,
|
104
|
-
]
|
105
|
-
: any;
|