jazz-tools 0.17.14 → 0.18.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/.svelte-kit/__package__/jazz.class.svelte.js +1 -1
- package/.svelte-kit/__package__/media/image.svelte +3 -9
- package/.svelte-kit/__package__/media/image.svelte.d.ts +1 -6
- package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/media/image.types.d.ts +7 -0
- package/.svelte-kit/__package__/media/image.types.d.ts.map +1 -0
- package/.svelte-kit/__package__/media/image.types.js +1 -0
- package/.svelte-kit/__package__/tests/media/image.svelte.test.js +31 -31
- package/.turbo/turbo-build.log +60 -46
- package/CHANGELOG.md +41 -0
- package/dist/better-auth/auth/client.d.ts +29 -0
- package/dist/better-auth/auth/client.d.ts.map +1 -0
- package/dist/better-auth/auth/client.js +127 -0
- package/dist/better-auth/auth/client.js.map +1 -0
- package/dist/better-auth/auth/react.d.ts +2170 -0
- package/dist/better-auth/auth/react.d.ts.map +1 -0
- package/dist/better-auth/auth/react.js +40 -0
- package/dist/better-auth/auth/react.js.map +1 -0
- package/dist/better-auth/auth/server.d.ts +14 -0
- package/dist/better-auth/auth/server.d.ts.map +1 -0
- package/dist/better-auth/auth/server.js +198 -0
- package/dist/better-auth/auth/server.js.map +1 -0
- package/dist/better-auth/auth/tests/client.test.d.ts +2 -0
- package/dist/better-auth/auth/tests/client.test.d.ts.map +1 -0
- package/dist/better-auth/auth/tests/server.test.d.ts +2 -0
- package/dist/better-auth/auth/tests/server.test.d.ts.map +1 -0
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/{chunk-LZOF6WP5.js → chunk-IERUTUXB.js} +1336 -1017
- package/dist/chunk-IERUTUXB.js.map +1 -0
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/inspector/{custom-element-ZSNTCECD.js → custom-element-WCY6D3QJ.js} +3 -3
- package/dist/inspector/{custom-element-ZSNTCECD.js.map → custom-element-WCY6D3QJ.js.map} +1 -1
- package/dist/inspector/index.js +1 -1
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/media/{chunk-E5J3WLQW.js → chunk-KR2V6X2N.js} +14 -9
- package/dist/media/chunk-KR2V6X2N.js.map +1 -0
- package/dist/media/create-image.d.ts +6 -6
- package/dist/media/index.browser.d.ts +6 -6
- package/dist/media/index.browser.js +1 -1
- package/dist/media/index.d.ts +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.native.d.ts +6 -6
- package/dist/media/index.native.js +1 -1
- package/dist/media/utils.d.ts.map +1 -1
- package/dist/prosemirror/index.js +2 -2
- package/dist/prosemirror/index.js.map +1 -1
- package/dist/react/index.js +7 -5
- package/dist/react/index.js.map +1 -1
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +4675 -23
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-native-core/index.js +1 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +1 -1
- package/dist/svelte/media/image.svelte +3 -9
- package/dist/svelte/media/image.svelte.d.ts +1 -6
- package/dist/svelte/media/image.svelte.d.ts.map +1 -1
- package/dist/svelte/media/image.types.d.ts +7 -0
- package/dist/svelte/media/image.types.d.ts.map +1 -0
- package/dist/svelte/media/image.types.js +1 -0
- package/dist/svelte/tests/media/image.svelte.test.js +31 -31
- package/dist/testing.js +18 -14
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/CoFieldInit.d.ts +13 -0
- package/dist/tools/coValues/CoFieldInit.d.ts.map +1 -0
- package/dist/tools/coValues/CoValueBase.d.ts +18 -15
- package/dist/tools/coValues/CoValueBase.d.ts.map +1 -1
- package/dist/tools/coValues/account.d.ts +101 -46
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/coFeed.d.ts +78 -62
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/coList.d.ts +212 -99
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +210 -192
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/coPlainText.d.ts +30 -22
- package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
- package/dist/tools/coValues/deepLoading.d.ts +13 -13
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/extensions/imageDef.d.ts +1 -1
- package/dist/tools/coValues/group.d.ts +32 -32
- package/dist/tools/coValues/group.d.ts.map +1 -1
- package/dist/tools/coValues/inbox.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +18 -17
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/coValues/profile.d.ts +6 -5
- package/dist/tools/coValues/profile.d.ts.map +1 -1
- package/dist/tools/coValues/schemaUnion.d.ts +3 -3
- package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/anonymousJazzAgent.d.ts +2 -1
- package/dist/tools/implementation/anonymousJazzAgent.d.ts.map +1 -1
- package/dist/tools/implementation/schema.d.ts +5 -5
- package/dist/tools/implementation/schema.d.ts.map +1 -1
- package/dist/tools/implementation/symbols.d.ts +2 -0
- package/dist/tools/implementation/symbols.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +6 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +8 -3
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +12 -7
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +13 -7
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +11 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +4 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +4 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/{CoFieldInit.d.ts → CoFieldSchemaInit.d.ts} +7 -7
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts.map +1 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts +3 -3
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/internal.d.ts +2 -1
- package/dist/tools/internal.d.ts.map +1 -1
- package/dist/tools/lib/migration.d.ts +1 -1
- package/dist/tools/lib/migration.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/index.d.ts +1 -1
- package/dist/tools/subscribe/index.d.ts.map +1 -1
- package/dist/tools/subscribe/utils.d.ts +2 -2
- package/dist/tools/subscribe/utils.d.ts.map +1 -1
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/utils.d.ts +2 -6
- package/dist/tools/tests/utils.d.ts.map +1 -1
- package/dist/worker/index.js +3 -3
- package/dist/worker/index.js.map +1 -1
- package/package.json +23 -4
- package/src/better-auth/auth/client.ts +169 -0
- package/src/better-auth/auth/react.tsx +105 -0
- package/src/better-auth/auth/server.ts +250 -0
- package/src/better-auth/auth/tests/client.test.ts +249 -0
- package/src/better-auth/auth/tests/server.test.ts +226 -0
- package/src/browser/auth/PasskeyAuth.ts +2 -2
- package/src/browser/createBrowserContext.ts +2 -2
- package/src/browser/tests/PasskeyAuth.test.ts +2 -2
- package/src/inspector/custom-element.tsx +2 -2
- package/src/inspector/viewer/new-app.tsx +1 -1
- package/src/media/create-image.test.ts +7 -7
- package/src/media/create-image.ts +5 -3
- package/src/media/index.ts +1 -1
- package/src/media/utils.test.ts +72 -66
- package/src/media/utils.ts +9 -6
- package/src/prosemirror/lib/plugin.ts +1 -1
- package/src/prosemirror/lib/sync.ts +1 -1
- package/src/prosemirror/tests/plugin.test.ts +4 -4
- package/src/react/media/image.tsx +2 -2
- package/src/react/tests/media/image.test.tsx +52 -32
- package/src/react-core/hooks.ts +11 -5
- package/src/react-core/tests/useAccount.test.ts +16 -22
- package/src/react-core/tests/useCoState.test.ts +19 -19
- package/src/react-core/tests/useInboxSender.test.ts +5 -2
- package/src/react-core/tests/usePassPhraseAuth.test.ts +6 -6
- package/src/react-native-core/media/image.tsx +1 -1
- package/src/svelte/jazz.class.svelte.ts +1 -1
- package/src/svelte/media/image.svelte +3 -9
- package/src/svelte/media/image.types.ts +7 -0
- package/src/svelte/tests/media/image.svelte.test.ts +34 -32
- package/src/tools/auth/DemoAuth.ts +2 -2
- package/src/tools/auth/PassphraseAuth.ts +2 -2
- package/src/tools/auth/clerk/index.ts +2 -2
- package/src/tools/auth/clerk/tests/JazzClerkAuth.test.ts +1 -1
- package/src/tools/coValues/CoFieldInit.ts +20 -0
- package/src/tools/coValues/CoValueBase.ts +40 -60
- package/src/tools/coValues/account.ts +311 -232
- package/src/tools/coValues/coFeed.ts +185 -153
- package/src/tools/coValues/coList.ts +507 -334
- package/src/tools/coValues/coMap.ts +434 -286
- package/src/tools/coValues/coPlainText.ts +94 -110
- package/src/tools/coValues/deepLoading.ts +13 -13
- package/src/tools/coValues/group.ts +100 -114
- package/src/tools/coValues/inbox.ts +16 -14
- package/src/tools/coValues/interfaces.ts +49 -31
- package/src/tools/coValues/profile.ts +8 -6
- package/src/tools/coValues/request.ts +9 -9
- package/src/tools/coValues/schemaUnion.ts +11 -5
- package/src/tools/exports.ts +1 -1
- package/src/tools/implementation/ContextManager.ts +4 -4
- package/src/tools/implementation/anonymousJazzAgent.ts +2 -1
- package/src/tools/implementation/createContext.ts +1 -1
- package/src/tools/implementation/devtoolsFormatters.ts +9 -9
- package/src/tools/implementation/invites.ts +2 -2
- package/src/tools/implementation/schema.ts +7 -7
- package/src/tools/implementation/symbols.ts +3 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +11 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +18 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +17 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +20 -11
- package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +19 -2
- package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +6 -0
- package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +6 -0
- package/src/tools/implementation/zodSchema/typeConverters/{CoFieldInit.ts → CoFieldSchemaInit.ts} +11 -11
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +4 -4
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.ts +4 -4
- package/src/tools/implementation/zodSchema/zodCo.ts +3 -3
- package/src/tools/internal.ts +2 -1
- package/src/tools/lib/migration.ts +5 -5
- package/src/tools/subscribe/SubscriptionScope.ts +32 -24
- package/src/tools/subscribe/index.ts +4 -4
- package/src/tools/subscribe/utils.ts +11 -11
- package/src/tools/testing.ts +17 -13
- package/src/tools/tests/ContextManager.test.ts +70 -59
- package/src/tools/tests/PassphraseAuth.test.ts +2 -2
- package/src/tools/tests/account.test.ts +188 -67
- package/src/tools/tests/coDiscriminatedUnion.test-d.ts +12 -6
- package/src/tools/tests/coDiscriminatedUnion.test.ts +26 -17
- package/src/tools/tests/coFeed.test-d.ts +18 -17
- package/src/tools/tests/coFeed.test.ts +108 -97
- package/src/tools/tests/coList.test-d.ts +18 -23
- package/src/tools/tests/coList.test.ts +350 -165
- package/src/tools/tests/coMap.record.test-d.ts +9 -13
- package/src/tools/tests/coMap.record.test.ts +37 -23
- package/src/tools/tests/coMap.test-d.ts +43 -21
- package/src/tools/tests/coMap.test.ts +459 -182
- package/src/tools/tests/coOptional.test.ts +28 -13
- package/src/tools/tests/coPlainText.test.ts +15 -15
- package/src/tools/tests/createContext.test.ts +14 -14
- package/src/tools/tests/deepLoading.test.ts +95 -94
- package/src/tools/tests/exportImport.test.ts +61 -41
- package/src/tools/tests/groupsAndAccounts.test.ts +333 -116
- package/src/tools/tests/inbox.test.ts +22 -17
- package/src/tools/tests/interfaces.test.ts +12 -11
- package/src/tools/tests/invites.test.ts +6 -4
- package/src/tools/tests/load.test.ts +20 -18
- package/src/tools/tests/patterns/notifications.test.ts +7 -7
- package/src/tools/tests/patterns/quest.test.ts +3 -3
- package/src/tools/tests/patterns/requestToJoin.test.ts +22 -22
- package/src/tools/tests/request.test.ts +38 -39
- package/src/tools/tests/schemaUnion.test.ts +64 -10
- package/src/tools/tests/subscribe.test.ts +64 -64
- package/src/tools/tests/testing.test.ts +7 -11
- package/src/tools/tests/utils.ts +3 -3
- package/src/tools/tests/zod.test.ts +3 -3
- package/src/worker/index.ts +3 -3
- package/tsup.config.ts +9 -0
- package/dist/chunk-LZOF6WP5.js.map +0 -1
- package/dist/media/chunk-E5J3WLQW.js.map +0 -1
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldInit.d.ts.map +0 -1
@@ -8,10 +8,12 @@ import {
|
|
8
8
|
type RawCoMap,
|
9
9
|
cojsonInternals,
|
10
10
|
} from "cojson";
|
11
|
-
import
|
11
|
+
import {
|
12
12
|
AnonymousJazzAgent,
|
13
|
+
CoFieldInit,
|
13
14
|
CoValue,
|
14
15
|
CoValueClass,
|
16
|
+
getCoValueOwner,
|
15
17
|
Group,
|
16
18
|
ID,
|
17
19
|
PartialOnUndefined,
|
@@ -24,10 +26,12 @@ import type {
|
|
24
26
|
Simplify,
|
25
27
|
SubscribeListenerOptions,
|
26
28
|
SubscribeRestArgs,
|
29
|
+
TypeSym,
|
27
30
|
} from "../internal.js";
|
28
31
|
import {
|
29
32
|
Account,
|
30
33
|
CoValueBase,
|
34
|
+
CoValueJazzApi,
|
31
35
|
ItemsSym,
|
32
36
|
Ref,
|
33
37
|
RegisteredSchemas,
|
@@ -57,6 +61,14 @@ type CoMapEdit<V> = {
|
|
57
61
|
|
58
62
|
type LastAndAllCoMapEdits<V> = CoMapEdit<V> & { all: CoMapEdit<V>[] };
|
59
63
|
|
64
|
+
type CoMapEdits<M extends CoMap> = {
|
65
|
+
[Key in CoKeys<M>]?: LastAndAllCoMapEdits<M[Key]>;
|
66
|
+
};
|
67
|
+
|
68
|
+
type CoMapFieldSchema = {
|
69
|
+
[key: string]: Schema;
|
70
|
+
} & { [ItemsSym]?: Schema };
|
71
|
+
|
60
72
|
/**
|
61
73
|
* CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
|
62
74
|
*
|
@@ -91,196 +103,44 @@ type LastAndAllCoMapEdits<V> = CoMapEdit<V> & { all: CoMapEdit<V>[] };
|
|
91
103
|
* @category CoValues
|
92
104
|
* */
|
93
105
|
export class CoMap extends CoValueBase implements CoValue {
|
94
|
-
/**
|
95
|
-
* The ID of this `CoMap`
|
96
|
-
* @category Content */
|
97
|
-
declare id: ID<this>;
|
98
106
|
/** @category Type Helpers */
|
99
|
-
declare
|
107
|
+
declare [TypeSym]: "CoMap";
|
100
108
|
static {
|
101
|
-
this.prototype
|
102
|
-
}
|
103
|
-
/** @category Internals */
|
104
|
-
declare _raw: RawCoMap;
|
105
|
-
|
106
|
-
/** @internal */
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
108
|
-
static _schema: any;
|
109
|
-
/** @internal */
|
110
|
-
get _schema() {
|
111
|
-
return (this.constructor as typeof CoMap)._schema as {
|
112
|
-
[key: string]: Schema;
|
113
|
-
} & { [ItemsSym]?: Schema };
|
114
|
-
}
|
115
|
-
|
116
|
-
/**
|
117
|
-
* The timestamp of the creation time of the CoMap
|
118
|
-
*/
|
119
|
-
get _createdAt() {
|
120
|
-
return this._raw.earliestTxMadeAt ?? Number.MAX_SAFE_INTEGER;
|
121
|
-
}
|
122
|
-
|
123
|
-
/**
|
124
|
-
* The timestamp of the last updated time of the CoMap
|
125
|
-
*/
|
126
|
-
get _lastUpdatedAt() {
|
127
|
-
return this._raw.latestTxMadeAt;
|
109
|
+
this.prototype[TypeSym] = "CoMap";
|
128
110
|
}
|
129
111
|
|
130
112
|
/**
|
131
|
-
*
|
132
|
-
* the `Ref` instead of the potentially loaded/null value.
|
133
|
-
*
|
134
|
-
* This allows you to always get the ID or load the value manually.
|
135
|
-
*
|
136
|
-
* @example
|
137
|
-
* ```ts
|
138
|
-
* person._refs.pet.id; // => ID<Animal>
|
139
|
-
* person._refs.pet.value;
|
140
|
-
* // => Animal | null
|
141
|
-
* const pet = await person._refs.pet.load();
|
142
|
-
* ```
|
113
|
+
* Jazz methods for CoMaps are inside this property.
|
143
114
|
*
|
144
|
-
*
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
? Key
|
150
|
-
: never]?: RefIfCoValue<this[Key]>;
|
151
|
-
} & {
|
152
|
-
[Key in CoKeys<this> as this[Key] extends undefined
|
153
|
-
? never
|
154
|
-
: this[Key] extends CoValue
|
155
|
-
? Key
|
156
|
-
: never]: RefIfCoValue<this[Key]>;
|
157
|
-
}
|
158
|
-
> {
|
159
|
-
return makeRefs<CoKeys<this>>(
|
160
|
-
this,
|
161
|
-
(key) => this._raw.get(key as string) as unknown as ID<CoValue>,
|
162
|
-
() => {
|
163
|
-
const keys = this._raw.keys().filter((key) => {
|
164
|
-
const descriptor = this.getDescriptor(key as string);
|
165
|
-
return (
|
166
|
-
descriptor && descriptor !== "json" && isRefEncoded(descriptor)
|
167
|
-
);
|
168
|
-
}) as CoKeys<this>[];
|
169
|
-
|
170
|
-
return keys;
|
171
|
-
},
|
172
|
-
this._loadedAs,
|
173
|
-
(key) => this.getDescriptor(key as string) as RefEncoded<CoValue>,
|
174
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
175
|
-
) as any;
|
176
|
-
}
|
115
|
+
* This allows CoMaps to be used as plain objects while still having
|
116
|
+
* access to Jazz methods, and also doesn't limit which key names can be
|
117
|
+
* used inside CoMaps.
|
118
|
+
*/
|
119
|
+
declare $jazz: CoMapJazzApi<this>;
|
177
120
|
|
178
121
|
/** @internal */
|
179
|
-
|
180
|
-
target: CoMap,
|
181
|
-
rawEdit: {
|
182
|
-
by: RawAccountID | AgentID;
|
183
|
-
tx: CojsonInternalTypes.TransactionID;
|
184
|
-
at: Date;
|
185
|
-
value?: JsonValue | undefined;
|
186
|
-
},
|
187
|
-
descriptor: Schema,
|
188
|
-
key: string,
|
189
|
-
) {
|
190
|
-
return {
|
191
|
-
value:
|
192
|
-
descriptor === "json"
|
193
|
-
? rawEdit.value
|
194
|
-
: "encoded" in descriptor
|
195
|
-
? rawEdit.value === null || rawEdit.value === undefined
|
196
|
-
? rawEdit.value
|
197
|
-
: descriptor.encoded.decode(rawEdit.value)
|
198
|
-
: accessChildById(target, rawEdit.value as string, descriptor),
|
199
|
-
ref:
|
200
|
-
descriptor !== "json" && isRefEncoded(descriptor)
|
201
|
-
? new Ref(
|
202
|
-
rawEdit.value as ID<CoValue>,
|
203
|
-
target._loadedAs,
|
204
|
-
descriptor,
|
205
|
-
target,
|
206
|
-
)
|
207
|
-
: undefined,
|
208
|
-
get by() {
|
209
|
-
return (
|
210
|
-
rawEdit.by &&
|
211
|
-
accessChildById(target, rawEdit.by, {
|
212
|
-
ref: Account,
|
213
|
-
optional: false,
|
214
|
-
})
|
215
|
-
);
|
216
|
-
},
|
217
|
-
madeAt: rawEdit.at,
|
218
|
-
key,
|
219
|
-
};
|
220
|
-
}
|
221
|
-
|
222
|
-
/** @category Collaboration */
|
223
|
-
get _edits() {
|
224
|
-
const map = this;
|
225
|
-
return new Proxy(
|
226
|
-
{},
|
227
|
-
{
|
228
|
-
get(_target, key) {
|
229
|
-
const rawEdit = map._raw.lastEditAt(key as string);
|
230
|
-
if (!rawEdit) return undefined;
|
231
|
-
|
232
|
-
const descriptor = map.getDescriptor(key as string);
|
233
|
-
|
234
|
-
if (!descriptor) return undefined;
|
235
|
-
|
236
|
-
return {
|
237
|
-
...map.getEditFromRaw(map, rawEdit, descriptor, key as string),
|
238
|
-
get all() {
|
239
|
-
return [...map._raw.editsAt(key as string)].map((rawEdit) =>
|
240
|
-
map.getEditFromRaw(map, rawEdit, descriptor, key as string),
|
241
|
-
);
|
242
|
-
},
|
243
|
-
};
|
244
|
-
},
|
245
|
-
ownKeys(_target) {
|
246
|
-
return map._raw.keys();
|
247
|
-
},
|
248
|
-
getOwnPropertyDescriptor(target, key) {
|
249
|
-
return {
|
250
|
-
value: Reflect.get(target, key),
|
251
|
-
writable: false,
|
252
|
-
enumerable: true,
|
253
|
-
configurable: true,
|
254
|
-
};
|
255
|
-
},
|
256
|
-
},
|
257
|
-
) as {
|
258
|
-
[Key in CoKeys<this>]?: LastAndAllCoMapEdits<this[Key]>;
|
259
|
-
};
|
260
|
-
}
|
122
|
+
static _schema: CoMapFieldSchema;
|
261
123
|
|
262
124
|
/** @internal */
|
263
|
-
constructor(
|
264
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
265
|
-
options: { fromRaw: RawCoMap } | undefined,
|
266
|
-
) {
|
125
|
+
constructor(options: { fromRaw: RawCoMap } | undefined) {
|
267
126
|
super();
|
268
127
|
|
128
|
+
const proxy = new Proxy(this, CoMapProxyHandler as ProxyHandler<this>);
|
129
|
+
|
269
130
|
if (options) {
|
270
131
|
if ("fromRaw" in options) {
|
271
132
|
Object.defineProperties(this, {
|
272
|
-
|
273
|
-
value:
|
133
|
+
$jazz: {
|
134
|
+
value: new CoMapJazzApi(proxy, () => options.fromRaw),
|
274
135
|
enumerable: false,
|
275
136
|
},
|
276
|
-
_raw: { value: options.fromRaw, enumerable: false },
|
277
137
|
});
|
278
138
|
} else {
|
279
139
|
throw new Error("Invalid CoMap constructor arguments");
|
280
140
|
}
|
281
141
|
}
|
282
142
|
|
283
|
-
return
|
143
|
+
return proxy;
|
284
144
|
}
|
285
145
|
|
286
146
|
/**
|
@@ -300,13 +160,15 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
300
160
|
* ```
|
301
161
|
*
|
302
162
|
* @category Creation
|
163
|
+
*
|
164
|
+
* @deprecated Use `co.map(...).create`.
|
303
165
|
**/
|
304
166
|
static create<M extends CoMap>(
|
305
167
|
this: CoValueClass<M>,
|
306
|
-
init: Simplify<
|
168
|
+
init: Simplify<CoMapInit_DEPRECATED<M>>,
|
307
169
|
options?:
|
308
170
|
| {
|
309
|
-
owner
|
171
|
+
owner?: Account | Group;
|
310
172
|
unique?: CoValueUniqueness["uniqueness"];
|
311
173
|
}
|
312
174
|
| Account
|
@@ -314,7 +176,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
314
176
|
) {
|
315
177
|
const instance = new this();
|
316
178
|
|
317
|
-
return
|
179
|
+
return CoMap._createCoMap(instance, init, options);
|
318
180
|
}
|
319
181
|
|
320
182
|
/**
|
@@ -323,25 +185,22 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
323
185
|
*/
|
324
186
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
325
187
|
toJSON(_key?: string, processedValues?: ID<CoValue>[]): any {
|
326
|
-
const result = {
|
327
|
-
id: this.id,
|
328
|
-
_type: this._type,
|
329
|
-
} as Record<string, any>;
|
188
|
+
const result = {} as Record<string, any>;
|
330
189
|
|
331
|
-
for (const key of this.
|
190
|
+
for (const key of this.$jazz.raw.keys()) {
|
332
191
|
const tKey = key as CoKeys<this>;
|
333
|
-
const descriptor = this.getDescriptor(tKey);
|
192
|
+
const descriptor = this.$jazz.getDescriptor(tKey);
|
334
193
|
|
335
194
|
if (!descriptor) {
|
336
195
|
continue;
|
337
196
|
}
|
338
197
|
|
339
198
|
if (descriptor == "json" || "encoded" in descriptor) {
|
340
|
-
result[key] = this.
|
199
|
+
result[key] = this.$jazz.raw.get(key);
|
341
200
|
} else if (isRefEncoded(descriptor)) {
|
342
|
-
const id = this.
|
201
|
+
const id = this.$jazz.raw.get(key) as ID<CoValue>;
|
343
202
|
|
344
|
-
if (processedValues?.includes(id) || id === this.id) {
|
203
|
+
if (processedValues?.includes(id) || id === this.$jazz.id) {
|
345
204
|
result[key] = { _circular: id };
|
346
205
|
continue;
|
347
206
|
}
|
@@ -356,7 +215,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
356
215
|
) {
|
357
216
|
const jsonedRef = ref.toJSON(tKey, [
|
358
217
|
...(processedValues || []),
|
359
|
-
this.id,
|
218
|
+
this.$jazz.id,
|
360
219
|
]);
|
361
220
|
result[key] = jsonedRef;
|
362
221
|
}
|
@@ -372,41 +231,45 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
372
231
|
return this.toJSON();
|
373
232
|
}
|
374
233
|
|
375
|
-
|
376
|
-
|
234
|
+
/**
|
235
|
+
* @internal
|
236
|
+
*/
|
237
|
+
static _createCoMap<M extends CoMap>(
|
238
|
+
instance: M,
|
239
|
+
init: Simplify<CoMapInit_DEPRECATED<M>>,
|
377
240
|
options?:
|
378
241
|
| {
|
379
|
-
owner
|
242
|
+
owner?: Account | Group;
|
380
243
|
unique?: CoValueUniqueness["uniqueness"];
|
381
244
|
}
|
382
245
|
| Account
|
383
246
|
| Group,
|
384
|
-
):
|
247
|
+
): M {
|
385
248
|
const { owner, uniqueness } = parseCoValueCreateOptions(options);
|
386
|
-
const raw = this.rawFromInit(init, owner, uniqueness);
|
387
249
|
|
388
|
-
Object.defineProperties(
|
389
|
-
|
390
|
-
value: raw
|
250
|
+
Object.defineProperties(instance, {
|
251
|
+
$jazz: {
|
252
|
+
value: new CoMapJazzApi(instance, () => raw),
|
391
253
|
enumerable: false,
|
392
254
|
},
|
393
|
-
_raw: { value: raw, enumerable: false },
|
394
255
|
});
|
395
256
|
|
396
|
-
|
257
|
+
const raw = CoMap.rawFromInit(instance, init, owner, uniqueness);
|
258
|
+
|
259
|
+
return instance;
|
397
260
|
}
|
398
261
|
|
399
262
|
/**
|
400
263
|
* Create a new `RawCoMap` from an initialization object
|
401
264
|
* @internal
|
402
265
|
*/
|
403
|
-
|
404
|
-
|
405
|
-
init: Simplify<
|
406
|
-
owner:
|
266
|
+
static rawFromInit<M extends CoMap, Fields extends object>(
|
267
|
+
instance: M,
|
268
|
+
init: Simplify<CoMapInit_DEPRECATED<Fields>> | undefined,
|
269
|
+
owner: Group,
|
407
270
|
uniqueness?: CoValueUniqueness,
|
408
271
|
) {
|
409
|
-
const rawOwner = owner.
|
272
|
+
const rawOwner = owner.$jazz.raw;
|
410
273
|
|
411
274
|
const rawInit = {} as {
|
412
275
|
[key in keyof Fields]: JsonValue | undefined;
|
@@ -416,7 +279,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
416
279
|
for (const key of Object.keys(init) as (keyof Fields)[]) {
|
417
280
|
const initValue = init[key as keyof typeof init];
|
418
281
|
|
419
|
-
const descriptor =
|
282
|
+
const descriptor = instance.$jazz.getDescriptor(key as string);
|
420
283
|
|
421
284
|
if (!descriptor) {
|
422
285
|
continue;
|
@@ -426,14 +289,14 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
426
289
|
rawInit[key] = initValue as JsonValue;
|
427
290
|
} else if (isRefEncoded(descriptor)) {
|
428
291
|
if (initValue != null) {
|
429
|
-
let refId = (initValue as unknown as CoValue)
|
292
|
+
let refId = (initValue as unknown as CoValue).$jazz?.id;
|
430
293
|
if (!refId) {
|
431
294
|
const coValue = instantiateRefEncodedWithInit(
|
432
295
|
descriptor,
|
433
296
|
initValue,
|
434
297
|
owner,
|
435
298
|
);
|
436
|
-
refId = coValue.id;
|
299
|
+
refId = coValue.$jazz.id;
|
437
300
|
}
|
438
301
|
rawInit[key] = refId;
|
439
302
|
}
|
@@ -448,10 +311,6 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
448
311
|
return rawOwner.createMap(rawInit, null, "private", uniqueness);
|
449
312
|
}
|
450
313
|
|
451
|
-
getDescriptor(key: string) {
|
452
|
-
return this._schema?.[key] || this._schema?.[ItemsSym];
|
453
|
-
}
|
454
|
-
|
455
314
|
/**
|
456
315
|
* Declare a Record-like CoMap schema, by extending `CoMap.Record(...)` and passing the value schema using `co`. Keys are always `string`.
|
457
316
|
*
|
@@ -500,6 +359,8 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
500
359
|
* ```
|
501
360
|
*
|
502
361
|
* @category Subscription & Loading
|
362
|
+
*
|
363
|
+
* @deprecated Use `co.map(...).load` instead.
|
503
364
|
*/
|
504
365
|
static load<M extends CoMap, const R extends RefsToResolve<M> = true>(
|
505
366
|
this: CoValueClass<M>,
|
@@ -539,6 +400,8 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
539
400
|
* ```
|
540
401
|
*
|
541
402
|
* @category Subscription & Loading
|
403
|
+
*
|
404
|
+
* @deprecated Use `co.map(...).subscribe` instead.
|
542
405
|
*/
|
543
406
|
static subscribe<M extends CoMap, const R extends RefsToResolve<M> = true>(
|
544
407
|
this: CoValueClass<M>,
|
@@ -589,7 +452,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
589
452
|
uniqueness: unique,
|
590
453
|
};
|
591
454
|
const crypto =
|
592
|
-
as
|
455
|
+
as[TypeSym] === "Anonymous" ? as.node.crypto : as.$jazz.localNode.crypto;
|
593
456
|
return cojsonInternals.idforHeader(header, crypto) as ID<M>;
|
594
457
|
}
|
595
458
|
|
@@ -615,6 +478,8 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
615
478
|
* @param options The options for creating or loading the CoMap. This includes the intended state of the CoMap, its unique identifier, its owner, and the references to resolve.
|
616
479
|
* @returns Either an existing & modified CoMap, or a new initialised CoMap if none exists.
|
617
480
|
* @category Subscription & Loading
|
481
|
+
*
|
482
|
+
* @deprecated Use `co.map(...).upsertUnique` instead.
|
618
483
|
*/
|
619
484
|
static async upsertUnique<
|
620
485
|
M extends CoMap,
|
@@ -622,7 +487,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
622
487
|
>(
|
623
488
|
this: CoValueClass<M>,
|
624
489
|
options: {
|
625
|
-
value: Simplify<
|
490
|
+
value: Simplify<CoMapInit_DEPRECATED<M>>;
|
626
491
|
unique: CoValueUniqueness["uniqueness"];
|
627
492
|
owner: Account | Group;
|
628
493
|
resolve?: RefsToResolveStrict<M, R>;
|
@@ -630,27 +495,29 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
630
495
|
): Promise<Resolved<M, R> | null> {
|
631
496
|
const mapId = CoMap._findUnique(
|
632
497
|
options.unique,
|
633
|
-
options.owner.id,
|
634
|
-
options.owner.
|
498
|
+
options.owner.$jazz.id,
|
499
|
+
options.owner.$jazz.loadedAs,
|
635
500
|
);
|
636
501
|
let map: Resolved<M, R> | null = await loadCoValueWithoutMe(this, mapId, {
|
637
502
|
...options,
|
638
|
-
loadAs: options.owner.
|
503
|
+
loadAs: options.owner.$jazz.loadedAs,
|
639
504
|
skipRetry: true,
|
640
505
|
});
|
641
506
|
if (!map) {
|
642
507
|
const instance = new this();
|
643
|
-
map =
|
508
|
+
map = CoMap._createCoMap(instance, options.value, {
|
644
509
|
owner: options.owner,
|
645
510
|
unique: options.unique,
|
646
511
|
}) as Resolved<M, R>;
|
647
512
|
} else {
|
648
|
-
(map as M).applyDiff(
|
513
|
+
(map as M).$jazz.applyDiff(
|
514
|
+
options.value as unknown as Partial<CoMapInit<M>>,
|
515
|
+
);
|
649
516
|
}
|
650
517
|
|
651
518
|
return await loadCoValueWithoutMe(this, mapId, {
|
652
519
|
...options,
|
653
|
-
loadAs: options.owner.
|
520
|
+
loadAs: options.owner.$jazz.loadedAs,
|
654
521
|
skipRetry: true,
|
655
522
|
});
|
656
523
|
}
|
@@ -661,6 +528,8 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
661
528
|
* @param ownerID The ID of the owner of the CoMap.
|
662
529
|
* @param options Additional options for loading the CoMap.
|
663
530
|
* @returns The loaded CoMap, or null if unavailable.
|
531
|
+
*
|
532
|
+
* @deprecated Use `co.map(...).loadUnique` instead.
|
664
533
|
*/
|
665
534
|
static loadUnique<M extends CoMap, const R extends RefsToResolve<M> = true>(
|
666
535
|
this: CoValueClass<M>,
|
@@ -677,48 +546,114 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
677
546
|
{ ...options, skipRetry: true },
|
678
547
|
);
|
679
548
|
}
|
549
|
+
}
|
550
|
+
|
551
|
+
/**
|
552
|
+
* Contains CoMap Jazz methods that are part of the {@link CoMap.$jazz`} property.
|
553
|
+
*/
|
554
|
+
class CoMapJazzApi<M extends CoMap> extends CoValueJazzApi<M> {
|
555
|
+
constructor(
|
556
|
+
private coMap: M,
|
557
|
+
private getRaw: () => RawCoMap,
|
558
|
+
) {
|
559
|
+
super(coMap);
|
560
|
+
}
|
680
561
|
|
681
562
|
/**
|
682
|
-
*
|
563
|
+
* The ID of this `CoMap`
|
564
|
+
* @category Content
|
565
|
+
*/
|
566
|
+
get id(): ID<M> {
|
567
|
+
return this.raw.id;
|
568
|
+
}
|
569
|
+
|
570
|
+
get owner(): Group {
|
571
|
+
return getCoValueOwner(this.coMap);
|
572
|
+
}
|
573
|
+
|
574
|
+
/**
|
575
|
+
* Check if a key is defined in the CoMap.
|
683
576
|
*
|
684
|
-
*
|
577
|
+
* This check does not load the referenced value or validate permissions.
|
685
578
|
*
|
686
|
-
* @
|
579
|
+
* @param key The key to check
|
580
|
+
* @returns True if the key is defined, false otherwise
|
581
|
+
* @category Content
|
687
582
|
*/
|
688
|
-
|
689
|
-
this
|
690
|
-
|
691
|
-
): Promise<Resolved<M, R>> {
|
692
|
-
return ensureCoValueLoaded(this, options);
|
583
|
+
has(key: CoKeys<M>): boolean {
|
584
|
+
const entry = this.raw.getRaw(key);
|
585
|
+
return entry?.change !== undefined && entry.change.op !== "del";
|
693
586
|
}
|
694
587
|
|
695
588
|
/**
|
696
|
-
*
|
589
|
+
* Set a value on the CoMap
|
697
590
|
*
|
698
|
-
*
|
591
|
+
* @param key The key to set
|
592
|
+
* @param value The value to set
|
699
593
|
*
|
700
|
-
*
|
594
|
+
* @category Content
|
595
|
+
*/
|
596
|
+
set<K extends CoKeys<M>>(key: K, value: CoFieldInit<M[K]>): void {
|
597
|
+
const descriptor = this.getDescriptor(key as string);
|
598
|
+
|
599
|
+
if (!descriptor) {
|
600
|
+
throw Error(`Cannot set unknown key ${key}`);
|
601
|
+
}
|
602
|
+
|
603
|
+
let refId = (value as CoValue)?.$jazz?.id;
|
604
|
+
if (descriptor === "json") {
|
605
|
+
this.raw.set(key, value as JsonValue | undefined);
|
606
|
+
} else if ("encoded" in descriptor) {
|
607
|
+
this.raw.set(key, descriptor.encoded.encode(value));
|
608
|
+
} else if (isRefEncoded(descriptor)) {
|
609
|
+
if (value === undefined) {
|
610
|
+
if (!descriptor.optional) {
|
611
|
+
throw Error(`Cannot set required reference ${key} to undefined`);
|
612
|
+
}
|
613
|
+
this.raw.set(key, null);
|
614
|
+
} else {
|
615
|
+
if (!refId) {
|
616
|
+
const coValue = instantiateRefEncodedWithInit(
|
617
|
+
descriptor,
|
618
|
+
value,
|
619
|
+
this.owner,
|
620
|
+
);
|
621
|
+
refId = coValue.$jazz.id;
|
622
|
+
}
|
623
|
+
this.raw.set(key, refId);
|
624
|
+
}
|
625
|
+
}
|
626
|
+
}
|
627
|
+
|
628
|
+
/**
|
629
|
+
* Delete a value from a CoMap.
|
701
630
|
*
|
702
|
-
*
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
subscribe<M extends CoMap, const R extends RefsToResolve<M>>(
|
714
|
-
this: M,
|
715
|
-
...args: SubscribeRestArgs<M, R>
|
716
|
-
): () => void {
|
717
|
-
const { options, listener } = parseSubscribeRestArgs(args);
|
718
|
-
return subscribeToExistingCoValue<M, R>(this, options, listener);
|
631
|
+
* For record-like CoMaps (created with `co.record`), any string key can be deleted.
|
632
|
+
* For struct-like CoMaps (created with `co.map`), only optional properties can be deleted.
|
633
|
+
*
|
634
|
+
* @param key The key to delete
|
635
|
+
*
|
636
|
+
* @category Content
|
637
|
+
*/
|
638
|
+
delete(
|
639
|
+
key: OptionalCoKeys<M> | (string extends keyof M ? string : never),
|
640
|
+
): void {
|
641
|
+
this.raw.delete(key);
|
719
642
|
}
|
720
643
|
|
721
|
-
|
644
|
+
/**
|
645
|
+
* Modify the `CoMap` to match another map.
|
646
|
+
*
|
647
|
+
* The new values are assigned to the CoMap, overwriting existing values
|
648
|
+
* when the property already exists.
|
649
|
+
*
|
650
|
+
* @param newValues - The new values to apply to the CoMap. For collaborative values,
|
651
|
+
* both CoValues and JSON values are supported.
|
652
|
+
* @returns The modified CoMap.
|
653
|
+
*
|
654
|
+
* @category Content
|
655
|
+
*/
|
656
|
+
applyDiff(newValues: Partial<CoMapInit<M>>): M {
|
722
657
|
for (const key in newValues) {
|
723
658
|
if (Object.prototype.hasOwnProperty.call(newValues, key)) {
|
724
659
|
const tKey = key as keyof typeof newValues & keyof this;
|
@@ -727,24 +662,64 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
727
662
|
if (!descriptor) continue;
|
728
663
|
|
729
664
|
const newValue = newValues[tKey];
|
730
|
-
const currentValue =
|
665
|
+
const currentValue = this.coMap[tKey];
|
731
666
|
|
732
667
|
if (descriptor === "json" || "encoded" in descriptor) {
|
733
668
|
if (currentValue !== newValue) {
|
734
|
-
|
735
|
-
(this as any)[tKey] = newValue;
|
669
|
+
this.set(tKey as any, newValue as CoFieldInit<M[keyof M]>);
|
736
670
|
}
|
737
671
|
} else if (isRefEncoded(descriptor)) {
|
738
|
-
const currentId = (currentValue as CoValue | undefined)
|
739
|
-
|
672
|
+
const currentId = (currentValue as CoValue | undefined)?.$jazz.id;
|
673
|
+
let newId = (newValue as CoValue | undefined)?.$jazz?.id;
|
740
674
|
if (currentId !== newId) {
|
741
|
-
|
742
|
-
(this as any)[tKey] = newValue;
|
675
|
+
this.set(tKey as any, newValue as CoFieldInit<M[keyof M]>);
|
743
676
|
}
|
744
677
|
}
|
745
678
|
}
|
746
679
|
}
|
747
|
-
return this;
|
680
|
+
return this.coMap;
|
681
|
+
}
|
682
|
+
|
683
|
+
/**
|
684
|
+
* Given an already loaded `CoMap`, ensure that the specified fields are loaded to the specified depth.
|
685
|
+
*
|
686
|
+
* Works like `CoMap.load()`, but you don't need to pass the ID or the account to load as again.
|
687
|
+
*
|
688
|
+
* @category Subscription & Loading
|
689
|
+
*/
|
690
|
+
ensureLoaded<Map extends CoMap, const R extends RefsToResolve<Map>>(
|
691
|
+
this: CoMapJazzApi<Map>,
|
692
|
+
options: {
|
693
|
+
resolve: RefsToResolveStrict<Map, R>;
|
694
|
+
},
|
695
|
+
): Promise<Resolved<Map, R>> {
|
696
|
+
return ensureCoValueLoaded(this.coMap, options);
|
697
|
+
}
|
698
|
+
|
699
|
+
/**
|
700
|
+
* Given an already loaded `CoMap`, subscribe to updates to the `CoMap` and ensure that the specified fields are loaded to the specified depth.
|
701
|
+
*
|
702
|
+
* Works like `CoMap.subscribe()`, but you don't need to pass the ID or the account to load as again.
|
703
|
+
*
|
704
|
+
* Returns an unsubscribe function that you should call when you no longer need updates.
|
705
|
+
*
|
706
|
+
* @category Subscription & Loading
|
707
|
+
**/
|
708
|
+
subscribe<Map extends CoMap, const R extends RefsToResolve<Map> = true>(
|
709
|
+
this: CoMapJazzApi<Map>,
|
710
|
+
listener: (value: Resolved<Map, R>, unsubscribe: () => void) => void,
|
711
|
+
): () => void;
|
712
|
+
subscribe<Map extends CoMap, const R extends RefsToResolve<Map> = true>(
|
713
|
+
this: CoMapJazzApi<Map>,
|
714
|
+
options: { resolve?: RefsToResolveStrict<Map, R> },
|
715
|
+
listener: (value: Resolved<Map, R>, unsubscribe: () => void) => void,
|
716
|
+
): () => void;
|
717
|
+
subscribe<Map extends CoMap, const R extends RefsToResolve<Map>>(
|
718
|
+
this: CoMapJazzApi<Map>,
|
719
|
+
...args: SubscribeRestArgs<Map, R>
|
720
|
+
): () => void {
|
721
|
+
const { options, listener } = parseSubscribeRestArgs(args);
|
722
|
+
return subscribeToExistingCoValue(this.coMap, options, listener);
|
748
723
|
}
|
749
724
|
|
750
725
|
/**
|
@@ -752,8 +727,134 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
752
727
|
*
|
753
728
|
* @category Subscription & Loading
|
754
729
|
*/
|
755
|
-
waitForSync(options?: { timeout?: number }) {
|
756
|
-
|
730
|
+
async waitForSync(options?: { timeout?: number }): Promise<void> {
|
731
|
+
await this.raw.core.waitForSync(options);
|
732
|
+
}
|
733
|
+
|
734
|
+
/**
|
735
|
+
* Get the descriptor for a given key
|
736
|
+
* @internal
|
737
|
+
*/
|
738
|
+
getDescriptor(key: string): Schema | undefined {
|
739
|
+
return this.schema?.[key] || this.schema?.[ItemsSym];
|
740
|
+
}
|
741
|
+
|
742
|
+
/**
|
743
|
+
* If property `prop` is a `coField.ref(...)`, you can use `coMap.$jazz.refs.prop` to access
|
744
|
+
* the `Ref` instead of the potentially loaded/null value.
|
745
|
+
*
|
746
|
+
* This allows you to always get the ID or load the value manually.
|
747
|
+
*
|
748
|
+
* @example
|
749
|
+
* ```ts
|
750
|
+
* person.$jazz.refs.pet.id; // => ID<Animal>
|
751
|
+
* person.$jazz.refs.pet.value;
|
752
|
+
* // => Animal | null
|
753
|
+
* const pet = await person.$jazz.refs.pet.load();
|
754
|
+
* ```
|
755
|
+
*
|
756
|
+
* @category Content
|
757
|
+
**/
|
758
|
+
get refs(): Simplify<
|
759
|
+
{
|
760
|
+
[Key in CoKeys<M> as NonNullable<M[Key]> extends CoValue
|
761
|
+
? Key
|
762
|
+
: never]?: RefIfCoValue<M[Key]>;
|
763
|
+
} & {
|
764
|
+
[Key in CoKeys<M> as M[Key] extends undefined
|
765
|
+
? never
|
766
|
+
: M[Key] extends CoValue
|
767
|
+
? Key
|
768
|
+
: never]: RefIfCoValue<M[Key]>;
|
769
|
+
}
|
770
|
+
> {
|
771
|
+
return makeRefs<CoKeys<this>>(
|
772
|
+
this.coMap,
|
773
|
+
(key) => this.raw.get(key as string) as unknown as ID<CoValue>,
|
774
|
+
() => {
|
775
|
+
const keys = this.raw.keys().filter((key) => {
|
776
|
+
const descriptor = this.getDescriptor(key as string);
|
777
|
+
return (
|
778
|
+
descriptor && descriptor !== "json" && isRefEncoded(descriptor)
|
779
|
+
);
|
780
|
+
}) as CoKeys<this>[];
|
781
|
+
|
782
|
+
return keys;
|
783
|
+
},
|
784
|
+
this.loadedAs,
|
785
|
+
(key) => this.getDescriptor(key as string) as RefEncoded<CoValue>,
|
786
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
787
|
+
) as any;
|
788
|
+
}
|
789
|
+
|
790
|
+
/**
|
791
|
+
* Get the edits made to the CoMap.
|
792
|
+
*
|
793
|
+
* @category Collaboration
|
794
|
+
*/
|
795
|
+
getEdits(): CoMapEdits<M> {
|
796
|
+
const map = this.coMap;
|
797
|
+
return new Proxy(
|
798
|
+
{},
|
799
|
+
{
|
800
|
+
get(_target, key) {
|
801
|
+
const rawEdit = map.$jazz.raw.lastEditAt(key as string);
|
802
|
+
if (!rawEdit) return undefined;
|
803
|
+
|
804
|
+
const descriptor = map.$jazz.getDescriptor(key as string);
|
805
|
+
|
806
|
+
if (!descriptor) return undefined;
|
807
|
+
|
808
|
+
return {
|
809
|
+
...getEditFromRaw(map, rawEdit, descriptor, key as string),
|
810
|
+
get all() {
|
811
|
+
return [...map.$jazz.raw.editsAt(key as string)].map((rawEdit) =>
|
812
|
+
getEditFromRaw(map, rawEdit, descriptor, key as string),
|
813
|
+
);
|
814
|
+
},
|
815
|
+
};
|
816
|
+
},
|
817
|
+
ownKeys(_target) {
|
818
|
+
return map.$jazz.raw.keys();
|
819
|
+
},
|
820
|
+
getOwnPropertyDescriptor(target, key) {
|
821
|
+
return {
|
822
|
+
value: Reflect.get(target, key),
|
823
|
+
writable: false,
|
824
|
+
enumerable: true,
|
825
|
+
configurable: true,
|
826
|
+
};
|
827
|
+
},
|
828
|
+
},
|
829
|
+
);
|
830
|
+
}
|
831
|
+
|
832
|
+
/** @internal */
|
833
|
+
override get raw() {
|
834
|
+
return this.getRaw();
|
835
|
+
}
|
836
|
+
|
837
|
+
/**
|
838
|
+
* The timestamp of the creation time of the CoMap
|
839
|
+
*
|
840
|
+
* @category Content
|
841
|
+
*/
|
842
|
+
get createdAt(): number {
|
843
|
+
return this.raw.earliestTxMadeAt ?? Number.MAX_SAFE_INTEGER;
|
844
|
+
}
|
845
|
+
|
846
|
+
/**
|
847
|
+
* The timestamp of the last updated time of the CoMap
|
848
|
+
*
|
849
|
+
* @category Content
|
850
|
+
*/
|
851
|
+
get lastUpdatedAt(): number {
|
852
|
+
return this.raw.latestTxMadeAt;
|
853
|
+
}
|
854
|
+
|
855
|
+
/** @internal */
|
856
|
+
get schema(): CoMapFieldSchema {
|
857
|
+
return (this.coMap.constructor as typeof CoMap)._schema;
|
757
858
|
}
|
758
859
|
}
|
759
860
|
|
@@ -762,6 +863,20 @@ export type CoKeys<Map extends object> = Exclude<
|
|
762
863
|
keyof CoMap
|
763
864
|
>;
|
764
865
|
|
866
|
+
/**
|
867
|
+
* Extract keys of properties that are required
|
868
|
+
*/
|
869
|
+
export type RequiredCoKeys<Map extends object> = {
|
870
|
+
[K in CoKeys<Map>]: undefined extends Map[K] ? never : K;
|
871
|
+
}[CoKeys<Map>];
|
872
|
+
|
873
|
+
/**
|
874
|
+
* Extract keys of properties that can be undefined
|
875
|
+
*/
|
876
|
+
export type OptionalCoKeys<Map extends object> = {
|
877
|
+
[K in CoKeys<Map>]: undefined extends Map[K] ? K : never;
|
878
|
+
}[CoKeys<Map>];
|
879
|
+
|
765
880
|
/**
|
766
881
|
* Force required ref fields to be non nullable
|
767
882
|
*
|
@@ -793,10 +908,16 @@ type ForceRequiredRef<V> = V extends InstanceType<CoValueClass> | null
|
|
793
908
|
? V | null
|
794
909
|
: V;
|
795
910
|
|
796
|
-
export type
|
911
|
+
export type CoMapInit_DEPRECATED<Map extends object> = PartialOnUndefined<{
|
797
912
|
[Key in CoKeys<Map>]: ForceRequiredRef<Map[Key]>;
|
798
913
|
}>;
|
799
914
|
|
915
|
+
export type CoMapInit<Map extends object> = {
|
916
|
+
[K in RequiredCoKeys<Map>]: CoFieldInit<Map[K]>;
|
917
|
+
} & {
|
918
|
+
[K in OptionalCoKeys<Map>]?: CoFieldInit<Map[K]> | undefined;
|
919
|
+
};
|
920
|
+
|
800
921
|
// TODO: cache handlers per descriptor for performance?
|
801
922
|
const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
802
923
|
get(target, key, receiver) {
|
@@ -809,13 +930,13 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
809
930
|
return undefined;
|
810
931
|
}
|
811
932
|
|
812
|
-
const descriptor = target.getDescriptor(key as string);
|
933
|
+
const descriptor = target.$jazz.getDescriptor(key as string);
|
813
934
|
|
814
935
|
if (!descriptor) {
|
815
936
|
return undefined;
|
816
937
|
}
|
817
938
|
|
818
|
-
const raw = target.
|
939
|
+
const raw = target.$jazz.raw.get(key);
|
819
940
|
|
820
941
|
if (descriptor === "json") {
|
821
942
|
return raw;
|
@@ -830,7 +951,7 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
830
951
|
},
|
831
952
|
set(target, key, value, receiver) {
|
832
953
|
if (
|
833
|
-
|
954
|
+
typeof key === "string" &&
|
834
955
|
typeof value === "object" &&
|
835
956
|
value !== null &&
|
836
957
|
SchemaInit in value
|
@@ -840,33 +961,12 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
840
961
|
return true;
|
841
962
|
}
|
842
963
|
|
843
|
-
const descriptor = target.getDescriptor(key as string);
|
964
|
+
const descriptor = target.$jazz.getDescriptor(key as string);
|
844
965
|
|
845
966
|
if (!descriptor) return false;
|
846
967
|
|
847
968
|
if (typeof key === "string") {
|
848
|
-
|
849
|
-
target._raw.set(key, value);
|
850
|
-
} else if ("encoded" in descriptor) {
|
851
|
-
target._raw.set(key, descriptor.encoded.encode(value));
|
852
|
-
} else if (isRefEncoded(descriptor)) {
|
853
|
-
if (value === undefined) {
|
854
|
-
if (descriptor.optional) {
|
855
|
-
target._raw.set(key, null);
|
856
|
-
} else {
|
857
|
-
throw new Error(
|
858
|
-
`Cannot set required reference ${key} to undefined`,
|
859
|
-
);
|
860
|
-
}
|
861
|
-
} else if (value?.id) {
|
862
|
-
target._raw.set(key, value.id);
|
863
|
-
} else {
|
864
|
-
throw new Error(
|
865
|
-
`Cannot set reference ${key} to a non-CoValue. Got ${value}`,
|
866
|
-
);
|
867
|
-
}
|
868
|
-
}
|
869
|
-
return true;
|
969
|
+
throw Error("Cannot update a CoMap directly. Use `$jazz.set` instead.");
|
870
970
|
} else {
|
871
971
|
return Reflect.set(target, key, value, receiver);
|
872
972
|
}
|
@@ -888,7 +988,7 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
888
988
|
ownKeys(target) {
|
889
989
|
const keys = Reflect.ownKeys(target).filter((k) => k !== ItemsSym);
|
890
990
|
|
891
|
-
for (const key of target.
|
991
|
+
for (const key of target.$jazz.raw.keys()) {
|
892
992
|
if (!keys.includes(key)) {
|
893
993
|
keys.push(key);
|
894
994
|
}
|
@@ -900,9 +1000,9 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
900
1000
|
if (key in target) {
|
901
1001
|
return Reflect.getOwnPropertyDescriptor(target, key);
|
902
1002
|
} else {
|
903
|
-
const descriptor = target.getDescriptor(key as string);
|
1003
|
+
const descriptor = target.$jazz.getDescriptor(key as string);
|
904
1004
|
|
905
|
-
if (descriptor || key in target.
|
1005
|
+
if (descriptor || key in target.$jazz.raw.latest) {
|
906
1006
|
return {
|
907
1007
|
enumerable: true,
|
908
1008
|
configurable: true,
|
@@ -912,20 +1012,24 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
912
1012
|
}
|
913
1013
|
},
|
914
1014
|
has(target, key) {
|
915
|
-
|
1015
|
+
// The `has` trap can be called when defining properties during CoMap creation
|
1016
|
+
// when using the class-based syntax. In that case, $jazz may not yet be initialized,
|
1017
|
+
// as it's defined afterwards in the create method.
|
1018
|
+
const descriptor = target.$jazz?.getDescriptor(key as string);
|
916
1019
|
|
917
|
-
if (target
|
918
|
-
return target.
|
1020
|
+
if (target.$jazz?.raw && typeof key === "string" && descriptor) {
|
1021
|
+
return target.$jazz.raw.get(key) !== undefined;
|
919
1022
|
} else {
|
920
1023
|
return Reflect.has(target, key);
|
921
1024
|
}
|
922
1025
|
},
|
923
1026
|
deleteProperty(target, key) {
|
924
|
-
const descriptor = target.getDescriptor(key as string);
|
1027
|
+
const descriptor = target.$jazz.getDescriptor(key as string);
|
925
1028
|
|
926
1029
|
if (typeof key === "string" && descriptor) {
|
927
|
-
|
928
|
-
|
1030
|
+
throw Error(
|
1031
|
+
"Cannot delete a CoMap property directly. Use `$jazz.delete` instead.",
|
1032
|
+
);
|
929
1033
|
} else {
|
930
1034
|
return Reflect.deleteProperty(target, key);
|
931
1035
|
}
|
@@ -933,3 +1037,47 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
933
1037
|
};
|
934
1038
|
|
935
1039
|
RegisteredSchemas["CoMap"] = CoMap;
|
1040
|
+
|
1041
|
+
/** @internal */
|
1042
|
+
function getEditFromRaw(
|
1043
|
+
target: CoMap,
|
1044
|
+
rawEdit: {
|
1045
|
+
by: RawAccountID | AgentID;
|
1046
|
+
tx: CojsonInternalTypes.TransactionID;
|
1047
|
+
at: Date;
|
1048
|
+
value?: JsonValue | undefined;
|
1049
|
+
},
|
1050
|
+
descriptor: Schema,
|
1051
|
+
key: string,
|
1052
|
+
) {
|
1053
|
+
return {
|
1054
|
+
value:
|
1055
|
+
descriptor === "json"
|
1056
|
+
? rawEdit.value
|
1057
|
+
: "encoded" in descriptor
|
1058
|
+
? rawEdit.value === null || rawEdit.value === undefined
|
1059
|
+
? rawEdit.value
|
1060
|
+
: descriptor.encoded.decode(rawEdit.value)
|
1061
|
+
: accessChildById(target, rawEdit.value as string, descriptor),
|
1062
|
+
ref:
|
1063
|
+
descriptor !== "json" && isRefEncoded(descriptor)
|
1064
|
+
? new Ref(
|
1065
|
+
rawEdit.value as ID<CoValue>,
|
1066
|
+
target.$jazz.loadedAs,
|
1067
|
+
descriptor,
|
1068
|
+
target,
|
1069
|
+
)
|
1070
|
+
: undefined,
|
1071
|
+
get by() {
|
1072
|
+
return (
|
1073
|
+
rawEdit.by &&
|
1074
|
+
accessChildById(target, rawEdit.by, {
|
1075
|
+
ref: Account,
|
1076
|
+
optional: false,
|
1077
|
+
})
|
1078
|
+
);
|
1079
|
+
},
|
1080
|
+
madeAt: rawEdit.at,
|
1081
|
+
key,
|
1082
|
+
};
|
1083
|
+
}
|