@pluv/treaty 0.0.0-stage → 5.2.3

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/README.md CHANGED
@@ -1,3 +1,18 @@
1
- # Temporary Holding Version
1
+ ## `@pluv/treaty`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > Isomorphic schema and procedure contract for [@pluv/io](https://www.npmjs.com/package/@pluv/io) and [@pluv/client](https://www.npmjs.com/package/@pluv/client)
4
+
5
+ **👉 See full documentation on [docs.pluv.io](https://docs.pluv.io/docs). 👈**
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # npm
11
+ npm install @pluv/treaty
12
+
13
+ # yarn
14
+ yarn add @pluv/treaty
15
+
16
+ # pnpm
17
+ pnpm add @pluv/treaty
18
+ ```
@@ -0,0 +1,154 @@
1
+ import { AbstractCrdtDocFactory, InferJson, InferStorage } from "@pluv/crdt";
2
+ import { BaseUser, DeepReadonly, OperatorUser, StandardSchemaV1, TreatyLike, TreatyProcedureLike, TreatyProceduresJson } from "@pluv/types";
3
+ type TreatyUserSchema<TUser extends BaseUser = BaseUser> = StandardSchemaV1<unknown, TUser>;
4
+ type TreatyPresenceSchema<TPresence extends Record<string, any> = Record<string, any>> = StandardSchemaV1<unknown, TPresence>;
5
+ type TreatyStorageSchema = AbstractCrdtDocFactory<any, any, any, any> & {
6
+ kind: "loro.doc" | "y.doc";
7
+ };
8
+ type InferSchemaOutput<TSchema> = TSchema extends StandardSchemaV1<any, infer TOutput> ? TOutput : never;
9
+ type InferTreatyUserOutput<TUserSchema> = InferSchemaOutput<TUserSchema> extends (infer TUser extends BaseUser) ? TUser : BaseUser;
10
+ type InferTreatyPresenceOutput<TPresenceSchema> = [TPresenceSchema] extends [undefined] ? Record<string, never> : InferSchemaOutput<TPresenceSchema> extends (infer TPresence extends Record<string, any>) ? TPresence : Record<string, never>;
11
+ type InferTreatyStorageNative<TStorage> = TStorage extends AbstractCrdtDocFactory<any, any, any, any> ? InferStorage<TStorage> : never;
12
+ type InferTreatyStorageJson<TStorage> = TStorage extends AbstractCrdtDocFactory<any, any, any, any> ? InferJson<TStorage> : never;
13
+ type TreatyResolverContext<TUser extends BaseUser, TPresence extends Record<string, any>, TJson extends Record<string, any>> = {
14
+ json: DeepReadonly<TJson>;
15
+ operator: OperatorUser | null;
16
+ presence: DeepReadonly<TPresence>;
17
+ user: TUser;
18
+ };
19
+ type TreatyResolverDoc<TJson extends Record<string, any>, TNative extends Record<string, any>> = {
20
+ get(): TNative;
21
+ toJson(): TJson;
22
+ };
23
+ type PresenceResolverContext<TUser extends BaseUser, TPresence extends Record<string, any>, TJson extends Record<string, any> = {}> = TreatyResolverContext<TUser, TPresence, TJson>;
24
+ type StoragePrepareContext<TUser extends BaseUser, TPresence extends Record<string, any> = {}> = {
25
+ operator: OperatorUser | null;
26
+ presence: DeepReadonly<TPresence>;
27
+ user: TUser;
28
+ };
29
+ type StorageResolverContext<TUser extends BaseUser, TJson extends Record<string, any>, TNative extends Record<string, any>, TPresence extends Record<string, any> = {}> = TreatyResolverContext<TUser, TPresence, TJson> & {
30
+ storage: TNative;
31
+ };
32
+ type JsonSchemaMethod = (options?: {
33
+ target?: string;
34
+ }) => unknown;
35
+ type JsonSchemaProducer = {
36
+ input: JsonSchemaMethod;
37
+ output?: JsonSchemaMethod;
38
+ };
39
+ type TreatyStorageResolveOptions = {
40
+ transact?: boolean;
41
+ };
42
+ type PresenceResolveResult<TPresence extends Record<string, any>> = Partial<TPresence> | Promise<Partial<TPresence>>;
43
+ type PresenceResolver<TInput extends Record<string, any>, TUser extends {
44
+ id: string;
45
+ }, TPresence extends Record<string, any>, TJson extends Record<string, any>> = (data: TInput, context: PresenceResolverContext<TUser, TPresence, TJson>) => PresenceResolveResult<TPresence>;
46
+ export declare class TreatyPresenceProcedure<TUser extends {
47
+ id: string;
48
+ }, TPresence extends Record<string, any>, TJson extends Record<string, any> = {}, TNative extends Record<string, any> = {}, TInput extends Record<string, any> = {}, TFilled extends "input" | "resolve" | "" = ""> implements TreatyProcedureLike<"presence", TInput> {
49
+ readonly kind: "presence";
50
+ private readonly _defs;
51
+ get config(): TreatyProcedureLike<"presence", TInput>["config"];
52
+ constructor(config?: TreatyProcedureLike<"presence", TInput>["config"]);
53
+ apply(data: unknown, params: {
54
+ doc: TreatyResolverDoc<TJson, TNative>;
55
+ operator?: OperatorUser | null;
56
+ presence?: TPresence | null;
57
+ user: TUser;
58
+ }): PresenceResolveResult<TPresence>;
59
+ input<TData extends Record<string, any>>(input: StandardSchemaV1<unknown, TData>): Omit<TreatyPresenceProcedure<TUser, TPresence, TJson, TNative, TData, TFilled | "input">, TFilled | "input">;
60
+ resolve(resolver: PresenceResolver<TInput, TUser, TPresence, TJson>): Omit<TreatyPresenceProcedure<TUser, TPresence, TJson, TNative, TInput, TFilled | "input" | "resolve">, TFilled | "input" | "resolve">;
61
+ }
62
+ declare const storageUnprepared: unique symbol;
63
+ type StorageUnprepared = typeof storageUnprepared;
64
+ type StoragePrepared<TPrepared> = [TPrepared] extends [StorageUnprepared] ? undefined : TPrepared;
65
+ type StoragePrepareFn<TInput extends Record<string, any>, TUser extends {
66
+ id: string;
67
+ }, TPresence extends Record<string, any>, TPrepared> = (data: TInput, context: StoragePrepareContext<TUser, TPresence>) => TPrepared | Promise<TPrepared>;
68
+ type StorageResolveFn<TInput extends Record<string, any>, TUser extends {
69
+ id: string;
70
+ }, TPresence extends Record<string, any>, TJson extends Record<string, any>, TNative extends Record<string, any>, TPrepared> = (data: TInput, context: StorageResolverContext<TUser, TJson, TNative, TPresence>, prepared: StoragePrepared<TPrepared>) => undefined;
71
+ type StorageProcedureConfig<TInput extends Record<string, any>, TUser extends {
72
+ id: string;
73
+ }, TPresence extends Record<string, any>, TJson extends Record<string, any>, TNative extends Record<string, any>, TPrepared> = {
74
+ input?: StandardSchemaV1<unknown, TInput> | null;
75
+ prepare?: StoragePrepareFn<TInput, TUser, TPresence, TPrepared> | null;
76
+ resolve?: StorageResolveFn<TInput, TUser, TPresence, TJson, TNative, TPrepared> | null;
77
+ transact?: boolean | null;
78
+ };
79
+ export declare class TreatyStorageProcedure<TUser extends {
80
+ id: string;
81
+ }, TJson extends Record<string, any>, TNative extends Record<string, any>, TPresence extends Record<string, any> = {}, TInput extends Record<string, any> = {}, TPrepared = StorageUnprepared, TFilled extends "input" | "prepare" | "resolve" | "" = ""> implements TreatyProcedureLike<"storage", TInput> {
82
+ readonly kind: "storage";
83
+ readonly prepared: [TPrepared] extends [StorageUnprepared] ? false : true;
84
+ private readonly _defs;
85
+ get config(): TreatyProcedureLike<"storage", TInput>["config"];
86
+ constructor(config?: StorageProcedureConfig<TInput, TUser, TPresence, TJson, TNative, TPrepared>);
87
+ load(data: unknown, params: {
88
+ operator?: OperatorUser | null;
89
+ presence?: TPresence | null;
90
+ user: TUser;
91
+ }): Promise<{
92
+ input: TInput;
93
+ prepared: StoragePrepared<TPrepared>;
94
+ }>;
95
+ apply(data: unknown, params: {
96
+ doc: TreatyResolverDoc<TJson, TNative>;
97
+ operator?: OperatorUser | null;
98
+ presence?: TPresence | null;
99
+ user: TUser;
100
+ }, prepared?: unknown): void;
101
+ input<TData extends Record<string, any>>(input: StandardSchemaV1<unknown, TData>): Omit<TreatyStorageProcedure<TUser, TJson, TNative, TPresence, TData, TPrepared, TFilled | "input">, TFilled | "input">;
102
+ prepare<TResult>(loader: StoragePrepareFn<TInput, TUser, TPresence, TResult>): Omit<TreatyStorageProcedure<TUser, TJson, TNative, TPresence, TInput, TResult, TFilled | "prepare">, TFilled | "prepare" | "input">;
103
+ resolve(resolver: (data: TInput, context: StorageResolverContext<TUser, TJson, TNative, TPresence>, prepared: StoragePrepared<TPrepared>) => undefined, options?: TreatyStorageResolveOptions): Omit<TreatyStorageProcedure<TUser, TJson, TNative, TPresence, TInput, TPrepared, TFilled | "input" | "prepare" | "resolve">, TFilled | "input" | "prepare" | "resolve">;
104
+ }
105
+ type PartitionPresence<TEvents extends Record<string, TreatyProcedureLike>> = { [K in keyof TEvents as TEvents[K] extends TreatyProcedureLike<"presence"> ? K : never]: TEvents[K]; };
106
+ type PartitionStorage<TEvents extends Record<string, TreatyProcedureLike>> = { [K in keyof TEvents as TEvents[K] extends TreatyProcedureLike<"storage"> ? K : never]: TEvents[K]; };
107
+ type HasPresenceSchema<TPresence> = [TPresence] extends [undefined] ? false : [TPresence] extends [never] ? false : true;
108
+ type HasStorageSchema<TStorage> = [TStorage] extends [undefined] ? false : [TStorage] extends [never] ? false : TStorage extends AbstractCrdtDocFactory<any, any, any, any> ? true : false;
109
+ type ResolverJson<TStorage> = [InferTreatyStorageJson<TStorage>] extends [never] ? {} : InferTreatyStorageJson<TStorage>;
110
+ type ResolverNative<TStorage> = [InferTreatyStorageNative<TStorage>] extends [never] ? {} : InferTreatyStorageNative<TStorage>;
111
+ type TreatyProcedureAccessors<TUserSchema extends StandardSchemaV1<unknown, BaseUser>, TPresenceSchema, TStorage> = (HasPresenceSchema<TPresenceSchema> extends true ? {
112
+ presence: TreatyPresenceProcedure<InferTreatyUserOutput<TUserSchema>, InferTreatyPresenceOutput<TPresenceSchema>, ResolverJson<TStorage>, ResolverNative<TStorage>>;
113
+ } : {}) & (HasStorageSchema<TStorage> extends true ? {
114
+ storage: TreatyStorageProcedure<InferTreatyUserOutput<TUserSchema>, ResolverJson<TStorage>, ResolverNative<TStorage>, InferTreatyPresenceOutput<TPresenceSchema>>;
115
+ } : {});
116
+ type RouterEventMap<TPresenceSchema, TStorage> = Record<string, (HasPresenceSchema<TPresenceSchema> extends true ? TreatyProcedureLike<"presence"> : never) | (HasStorageSchema<TStorage> extends true ? TreatyProcedureLike<"storage"> : never)>;
117
+ type MergeTreatyProcedureMaps<TTreaties extends readonly Treaty<any, any, any, any, any>[], TPresence extends Record<string, any>, TStorage extends Record<string, any>> = TTreaties extends readonly [infer IHead extends Treaty<any, any, any, any, any>, ...infer ITail extends Treaty<any, any, any, any, any>[]] ? MergeTreatyProcedureMaps<ITail, TPresence & IHead["_defs"]["procedures"]["presence"], TStorage & IHead["_defs"]["procedures"]["storage"]> : {
118
+ presence: TPresence;
119
+ storage: TStorage;
120
+ };
121
+ type CreateTreatyConfig<TUserSchema extends StandardSchemaV1<unknown, BaseUser>, TPresenceSchema extends StandardSchemaV1<any, any> | undefined = undefined, TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined = undefined> = {
122
+ user: TUserSchema;
123
+ presence?: TPresenceSchema;
124
+ storage?: TStorage;
125
+ };
126
+ export declare class Treaty<TUserSchema extends StandardSchemaV1<unknown, BaseUser> = StandardSchemaV1<unknown, BaseUser>, TPresenceSchema extends StandardSchemaV1<any, any> | undefined = StandardSchemaV1<any, any> | undefined, TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined = AbstractCrdtDocFactory<any, any, any, any> | undefined, TPresenceProcedures extends Record<string, TreatyProcedureLike<"presence">> = {}, TStorageProcedures extends Record<string, TreatyProcedureLike<"storage">> = {}> implements TreatyLike {
127
+ readonly user: TUserSchema;
128
+ readonly presence: TPresenceSchema;
129
+ readonly storage: TStorage;
130
+ readonly _defs: {
131
+ user: TUserSchema;
132
+ presence: TPresenceSchema;
133
+ storage: TStorage;
134
+ procedures: {
135
+ presence: TPresenceProcedures;
136
+ storage: TStorageProcedures;
137
+ };
138
+ };
139
+ get procedure(): TreatyProcedureAccessors<TUserSchema, TPresenceSchema, TStorage>;
140
+ constructor(config: CreateTreatyConfig<TUserSchema, TPresenceSchema, TStorage>, procedures?: {
141
+ presence: TPresenceProcedures;
142
+ storage: TStorageProcedures;
143
+ });
144
+ mergeRouters<TTreaties extends Treaty<TUserSchema, TPresenceSchema, TStorage, any, any>[]>(...treaties: TTreaties): Treaty<TUserSchema, TPresenceSchema, TStorage, MergeTreatyProcedureMaps<TTreaties, TPresenceProcedures, TStorageProcedures>["presence"], MergeTreatyProcedureMaps<TTreaties, TPresenceProcedures, TStorageProcedures>["storage"]>;
145
+ router<TEvents extends RouterEventMap<TPresenceSchema, TStorage>>(events: TEvents): Treaty<TUserSchema, TPresenceSchema, TStorage, TPresenceProcedures & PartitionPresence<TEvents>, TStorageProcedures & PartitionStorage<TEvents>>;
146
+ toUserJson(): unknown;
147
+ toPresenceJson(): unknown;
148
+ toStorageJson(): unknown;
149
+ toProceduresJson(): TreatyProceduresJson<TPresenceProcedures, TStorageProcedures>;
150
+ private toProcedureInputs;
151
+ }
152
+ export declare const createTreaty: <TUserSchema extends StandardSchemaV1<unknown, BaseUser>, TPresenceSchema extends StandardSchemaV1<any, any> | undefined = undefined, TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined = undefined>(config: CreateTreatyConfig<TUserSchema, TPresenceSchema, TStorage>) => Treaty<TUserSchema, TPresenceSchema, TStorage>;
153
+ export type { CreateTreatyConfig, InferSchemaOutput, InferTreatyPresenceOutput, InferTreatyStorageJson, InferTreatyStorageNative, InferTreatyUserOutput, JsonSchemaMethod, JsonSchemaProducer, PresenceResolverContext, StoragePrepareContext, StorageResolverContext, TreatyPresenceSchema, TreatyResolverContext, TreatyStorageResolveOptions, TreatyStorageSchema, TreatyUserSchema };
154
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/TreatyPresenceProcedure.ts","../src/TreatyStorageProcedure.ts","../src/Treaty.ts","../src/createTreaty.ts"],"mappings":"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"}
package/dist/index.mjs ADDED
@@ -0,0 +1,288 @@
1
+ // src/parseProcedureInput.ts
2
+ const parseProcedureInput = (schema, data) => {
3
+ if (!schema) return data;
4
+ const result = schema["~standard"].validate(data);
5
+ if (result instanceof Promise) throw new Error("Async schemas are not supported. Schema validate() must be synchronous.");
6
+ if (result.issues) throw new Error(result.issues[0]?.message ?? "Invalid input");
7
+ return result.value;
8
+ };
9
+ // src/toPresenceResolverContext.ts
10
+ const toPresenceResolverContext = (params) => {
11
+ const { doc, user } = params;
12
+ let json;
13
+ return {
14
+ get json() {
15
+ return json ??= doc.toJson();
16
+ },
17
+ operator: params.operator ?? null,
18
+ presence: JSON.parse(JSON.stringify(params.presence ?? {})),
19
+ user
20
+ };
21
+ };
22
+ // src/TreatyPresenceProcedure.ts
23
+ var TreatyPresenceProcedure = class TreatyPresenceProcedure {
24
+ kind = "presence";
25
+ _defs;
26
+ get config() {
27
+ return this._defs;
28
+ }
29
+ constructor(config = {}) {
30
+ this._defs = {
31
+ input: config.input ?? null,
32
+ resolve: config.resolve ?? null
33
+ };
34
+ }
35
+ apply(data, params) {
36
+ if (!this._defs.resolve) throw new Error("Treaty presence procedure is missing resolve");
37
+ const parsed = parseProcedureInput(this._defs.input, data);
38
+ return this._defs.resolve(parsed, toPresenceResolverContext(params));
39
+ }
40
+ input(input) {
41
+ return new TreatyPresenceProcedure({ input });
42
+ }
43
+ resolve(resolver) {
44
+ if (this._defs.resolve) throw new Error("Resolve was already defined for this procedure");
45
+ return new TreatyPresenceProcedure({
46
+ ...this._defs,
47
+ resolve: resolver
48
+ });
49
+ }
50
+ };
51
+ // src/toStorageResolverContext.ts
52
+ const toStorageResolverContext = (params) => {
53
+ const { doc, user } = params;
54
+ let json;
55
+ return {
56
+ get json() {
57
+ return json ??= doc.toJson();
58
+ },
59
+ operator: params.operator ?? null,
60
+ presence: JSON.parse(JSON.stringify(params.presence ?? {})),
61
+ storage: doc.get(),
62
+ user
63
+ };
64
+ };
65
+ // src/utils/getJsonSchemaProducer.ts
66
+ const getJsonSchemaProducer = (schema) => {
67
+ const jsonSchema = schema?.["~standard"]?.jsonSchema;
68
+ if (!jsonSchema || typeof jsonSchema.input !== "function") return null;
69
+ return jsonSchema;
70
+ };
71
+ // src/utils/JsonSchemaError.ts
72
+ var JsonSchemaError = class extends Error {
73
+ constructor() {
74
+ super("Schema must implement Standard Schema and Standard JSON Schema on the same object (e.g. Zod 4.2+ or ArkType).");
75
+ this.name = "JsonSchemaError";
76
+ }
77
+ };
78
+ // src/utils/assertions.ts
79
+ const assertResolvedProcedure = (name, kind, procedure) => {
80
+ if (typeof procedure.apply !== "function" || !procedure.config.resolve) throw new Error(`Treaty ${kind} procedure "${name}" is missing resolve`);
81
+ };
82
+ const assertSerializingSchema = (schema) => {
83
+ const producer = getJsonSchemaProducer(schema);
84
+ if (!producer) throw new JsonSchemaError();
85
+ return producer;
86
+ };
87
+ const assertOutputJsonSchema = (schema) => {
88
+ const producer = assertSerializingSchema(schema);
89
+ if (typeof producer.output !== "function") throw new JsonSchemaError();
90
+ return producer;
91
+ };
92
+ // src/utils/isAsyncFunction.ts
93
+ const asyncFunction = (async () => void 0).constructor;
94
+ const isAsyncFunction = (value) => value.constructor === asyncFunction;
95
+ // src/utils/toJsonSchema.ts
96
+ const JSON_SCHEMA_TARGET = "draft-2020-12";
97
+ const emitJsonSchema = (produce) => {
98
+ if (typeof produce !== "function") throw new JsonSchemaError();
99
+ return produce({ target: JSON_SCHEMA_TARGET });
100
+ };
101
+ const toInputJsonSchema = (schema) => {
102
+ return emitJsonSchema(schema.input);
103
+ };
104
+ const toOutputJsonSchema = (schema) => {
105
+ return emitJsonSchema(schema.output);
106
+ };
107
+ // src/TreatyStorageProcedure.ts
108
+ const isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
109
+ const toStoragePrepareContext = (params) => {
110
+ return {
111
+ operator: params.operator ?? null,
112
+ presence: JSON.parse(JSON.stringify(params.presence ?? {})),
113
+ user: params.user
114
+ };
115
+ };
116
+ var TreatyStorageProcedure = class TreatyStorageProcedure {
117
+ kind = "storage";
118
+ prepared;
119
+ _defs;
120
+ get config() {
121
+ return this._defs;
122
+ }
123
+ constructor(config = {}) {
124
+ const prepare = config.prepare ?? null;
125
+ this.prepared = prepare !== null;
126
+ this._defs = {
127
+ input: config.input ?? null,
128
+ prepare,
129
+ resolve: config.resolve ?? null,
130
+ transact: config.transact ?? true
131
+ };
132
+ }
133
+ async load(data, params) {
134
+ const input = parseProcedureInput(this._defs.input, data);
135
+ if (!this._defs.prepare) return {
136
+ input,
137
+ prepared: void 0
138
+ };
139
+ return {
140
+ input,
141
+ prepared: await this._defs.prepare(input, toStoragePrepareContext(params))
142
+ };
143
+ }
144
+ apply(data, params, prepared) {
145
+ if (!this._defs.resolve) throw new Error("Treaty storage procedure is missing resolve");
146
+ if (isAsyncFunction(this._defs.resolve)) throw new Error("Treaty storage procedure resolve must be synchronous");
147
+ const parsed = this.prepared ? data : parseProcedureInput(this._defs.input, data);
148
+ const result = this._defs.resolve(parsed, toStorageResolverContext(params), prepared);
149
+ if (isThenable(result)) {
150
+ Promise.resolve(result).catch(() => void 0);
151
+ throw new Error("Treaty storage procedure resolve must be synchronous");
152
+ }
153
+ }
154
+ input(input) {
155
+ return new TreatyStorageProcedure({
156
+ input,
157
+ prepare: this._defs.prepare,
158
+ transact: this._defs.transact
159
+ });
160
+ }
161
+ prepare(loader) {
162
+ if (this._defs.prepare) throw new Error("Prepare was already defined for this procedure");
163
+ return new TreatyStorageProcedure({
164
+ input: this._defs.input,
165
+ prepare: loader,
166
+ transact: this._defs.transact
167
+ });
168
+ }
169
+ resolve(resolver, options = {}) {
170
+ if (this._defs.resolve) throw new Error("Resolve was already defined for this procedure");
171
+ return new TreatyStorageProcedure({
172
+ input: this._defs.input,
173
+ prepare: this._defs.prepare,
174
+ resolve: resolver,
175
+ transact: options.transact ?? true
176
+ });
177
+ }
178
+ };
179
+ // src/Treaty.ts
180
+ var Treaty = class Treaty {
181
+ user;
182
+ presence;
183
+ storage;
184
+ _defs;
185
+ get procedure() {
186
+ const accessors = {};
187
+ if (this.presence) accessors.presence = new TreatyPresenceProcedure();
188
+ if (this.storage) accessors.storage = new TreatyStorageProcedure();
189
+ return accessors;
190
+ }
191
+ constructor(config, procedures = {
192
+ presence: {},
193
+ storage: {}
194
+ }) {
195
+ this.user = config.user;
196
+ this.presence = config.presence;
197
+ this.storage = config.storage;
198
+ this._defs = {
199
+ user: this.user,
200
+ presence: this.presence,
201
+ storage: this.storage,
202
+ procedures
203
+ };
204
+ }
205
+ mergeRouters(...treaties) {
206
+ const presence = Object.create(null);
207
+ const storage = Object.create(null);
208
+ for (const treaty of [this, ...treaties]) {
209
+ for (const name of Object.keys(treaty._defs.procedures.presence)) {
210
+ if (Object.hasOwn(presence, name)) throw new Error(`Duplicate presence procedure "${name}" when merging treaty routers`);
211
+ presence[name] = treaty._defs.procedures.presence[name];
212
+ }
213
+ for (const name of Object.keys(treaty._defs.procedures.storage)) {
214
+ if (Object.hasOwn(storage, name)) throw new Error(`Duplicate storage procedure "${name}" when merging treaty routers`);
215
+ storage[name] = treaty._defs.procedures.storage[name];
216
+ }
217
+ }
218
+ return new Treaty({
219
+ user: this.user,
220
+ presence: this.presence,
221
+ storage: this.storage
222
+ }, {
223
+ presence,
224
+ storage
225
+ });
226
+ }
227
+ router(events) {
228
+ const presence = Object.assign(Object.create(null), this._defs.procedures.presence);
229
+ const storage = Object.assign(Object.create(null), this._defs.procedures.storage);
230
+ Object.entries(events).forEach(([name, procedure]) => {
231
+ if (procedure.kind === "presence") {
232
+ if (Object.hasOwn(presence, name)) throw new Error(`Duplicate presence procedure "${name}"`);
233
+ assertResolvedProcedure(name, "presence", procedure);
234
+ presence[name] = procedure;
235
+ return;
236
+ }
237
+ if (procedure.kind === "storage") {
238
+ if (Object.hasOwn(storage, name)) throw new Error(`Duplicate storage procedure "${name}"`);
239
+ assertResolvedProcedure(name, "storage", procedure);
240
+ storage[name] = procedure;
241
+ return;
242
+ }
243
+ throw new Error(`Unknown treaty procedure kind for "${name}"`);
244
+ });
245
+ return new Treaty({
246
+ user: this.user,
247
+ presence: this.presence,
248
+ storage: this.storage
249
+ }, {
250
+ presence,
251
+ storage
252
+ });
253
+ }
254
+ toUserJson() {
255
+ return toOutputJsonSchema(assertOutputJsonSchema(this.user));
256
+ }
257
+ toPresenceJson() {
258
+ if (!this.presence) throw new Error("Treaty has no presence schema");
259
+ return toOutputJsonSchema(assertOutputJsonSchema(this.presence));
260
+ }
261
+ toStorageJson() {
262
+ const storage = this.storage;
263
+ if (!storage || typeof storage.toJSON !== "function") throw new Error("Treaty has no storage schema");
264
+ return storage.toJSON();
265
+ }
266
+ toProceduresJson() {
267
+ return {
268
+ presence: this.toProcedureInputs(this._defs.procedures.presence),
269
+ storage: this.toProcedureInputs(this._defs.procedures.storage)
270
+ };
271
+ }
272
+ toProcedureInputs(procedures) {
273
+ return Object.entries(procedures).reduce((acc, [name, procedure]) => {
274
+ const input = procedure.config.input;
275
+ acc[name] = { input: input ? toInputJsonSchema(assertSerializingSchema(input)) : null };
276
+ return acc;
277
+ }, Object.create(null));
278
+ }
279
+ };
280
+ // src/createTreaty.ts
281
+ const createTreaty = (config) => {
282
+ assertOutputJsonSchema(config.user);
283
+ if (config.presence) assertOutputJsonSchema(config.presence);
284
+ return new Treaty(config);
285
+ };
286
+ export { Treaty, TreatyPresenceProcedure, TreatyStorageProcedure, createTreaty };
287
+
288
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/parseProcedureInput.ts","../src/toPresenceResolverContext.ts","../src/TreatyPresenceProcedure.ts","../src/toStorageResolverContext.ts","../src/utils/getJsonSchemaProducer.ts","../src/utils/JsonSchemaError.ts","../src/utils/assertions.ts","../src/utils/isAsyncFunction.ts","../src/utils/toJsonSchema.ts","../src/TreatyStorageProcedure.ts","../src/Treaty.ts","../src/createTreaty.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@pluv/types\";\n\nexport const parseProcedureInput = <TData>(\n schema: StandardSchemaV1<unknown, TData> | null,\n data: unknown,\n): TData => {\n if (!schema) return data as TData;\n\n const result = schema[\"~standard\"].validate(data);\n\n if (result instanceof Promise) {\n throw new Error(\"Async schemas are not supported. Schema validate() must be synchronous.\");\n }\n\n if (result.issues) {\n throw new Error(result.issues[0]?.message ?? \"Invalid input\");\n }\n\n return result.value as TData;\n};\n","import type { BaseUser, DeepReadonly, OperatorUser } from \"@pluv/types\";\nimport type { PresenceResolverContext, TreatyResolverDoc } from \"./types\";\n\nexport const toPresenceResolverContext = <\n TUser extends BaseUser,\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n>(params: {\n doc: TreatyResolverDoc<TJson, TNative>;\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n}): PresenceResolverContext<TUser, TPresence, TJson> => {\n const { doc, user } = params;\n let json: DeepReadonly<TJson> | undefined;\n\n return {\n get json() {\n return (json ??= doc.toJson() as DeepReadonly<TJson>);\n },\n operator: params.operator ?? null,\n presence: JSON.parse(JSON.stringify(params.presence ?? {})) as DeepReadonly<TPresence>,\n user,\n };\n};\n","import type { OperatorUser, StandardSchemaV1, TreatyProcedureLike } from \"@pluv/types\";\nimport { parseProcedureInput } from \"./parseProcedureInput\";\nimport { toPresenceResolverContext } from \"./toPresenceResolverContext\";\nimport type { PresenceResolverContext, TreatyResolverDoc } from \"./types\";\n\ntype PresenceResolveResult<TPresence extends Record<string, any>> =\n | Partial<TPresence>\n | Promise<Partial<TPresence>>;\n\ntype PresenceResolver<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n> = (\n data: TInput,\n context: PresenceResolverContext<TUser, TPresence, TJson>,\n) => PresenceResolveResult<TPresence>;\n\ntype PresenceProcedureDefs<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n _TNative extends Record<string, any>,\n> = {\n input: StandardSchemaV1<unknown, TInput> | null;\n resolve: PresenceResolver<TInput, TUser, TPresence, TJson> | null;\n};\n\nexport class TreatyPresenceProcedure<\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any> = {},\n TNative extends Record<string, any> = {},\n TInput extends Record<string, any> = {},\n TFilled extends \"input\" | \"resolve\" | \"\" = \"\",\n> implements TreatyProcedureLike<\"presence\", TInput> {\n public readonly kind = \"presence\" as const;\n\n private readonly _defs: PresenceProcedureDefs<TInput, TUser, TPresence, TJson, TNative>;\n\n public get config(): TreatyProcedureLike<\"presence\", TInput>[\"config\"] {\n return this._defs;\n }\n\n constructor(config: TreatyProcedureLike<\"presence\", TInput>[\"config\"] = {}) {\n this._defs = {\n input: config.input ?? null,\n resolve:\n (config.resolve as\n | PresenceResolver<TInput, TUser, TPresence, TJson>\n | null\n | undefined) ?? null,\n };\n }\n\n public apply(\n data: unknown,\n params: {\n doc: TreatyResolverDoc<TJson, TNative>;\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n },\n ): PresenceResolveResult<TPresence> {\n if (!this._defs.resolve) {\n throw new Error(\"Treaty presence procedure is missing resolve\");\n }\n\n const parsed = parseProcedureInput(this._defs.input, data);\n\n return this._defs.resolve(parsed, toPresenceResolverContext(params));\n }\n\n public input<TData extends Record<string, any>>(\n input: StandardSchemaV1<unknown, TData>,\n ): Omit<\n TreatyPresenceProcedure<TUser, TPresence, TJson, TNative, TData, TFilled | \"input\">,\n TFilled | \"input\"\n > {\n return new TreatyPresenceProcedure<\n TUser,\n TPresence,\n TJson,\n TNative,\n TData,\n TFilled | \"input\"\n >({\n input,\n }) as Omit<\n TreatyPresenceProcedure<TUser, TPresence, TJson, TNative, TData, TFilled | \"input\">,\n TFilled | \"input\"\n >;\n }\n\n public resolve(\n resolver: PresenceResolver<TInput, TUser, TPresence, TJson>,\n ): Omit<\n TreatyPresenceProcedure<\n TUser,\n TPresence,\n TJson,\n TNative,\n TInput,\n TFilled | \"input\" | \"resolve\"\n >,\n TFilled | \"input\" | \"resolve\"\n > {\n if (this._defs.resolve) throw new Error(\"Resolve was already defined for this procedure\");\n\n return new TreatyPresenceProcedure<\n TUser,\n TPresence,\n TJson,\n TNative,\n TInput,\n TFilled | \"input\" | \"resolve\"\n >({\n ...this._defs,\n resolve: resolver,\n }) as Omit<\n TreatyPresenceProcedure<\n TUser,\n TPresence,\n TJson,\n TNative,\n TInput,\n TFilled | \"input\" | \"resolve\"\n >,\n TFilled | \"input\" | \"resolve\"\n >;\n }\n}\n","import type { BaseUser, DeepReadonly, OperatorUser } from \"@pluv/types\";\nimport type { StorageResolverContext, TreatyResolverDoc } from \"./types\";\n\nexport const toStorageResolverContext = <\n TUser extends BaseUser,\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n>(params: {\n doc: TreatyResolverDoc<TJson, TNative>;\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n}): StorageResolverContext<TUser, TJson, TNative, TPresence> => {\n const { doc, user } = params;\n let json: DeepReadonly<TJson> | undefined;\n\n return {\n get json() {\n return (json ??= doc.toJson() as DeepReadonly<TJson>);\n },\n operator: params.operator ?? null,\n presence: JSON.parse(JSON.stringify(params.presence ?? {})) as DeepReadonly<TPresence>,\n storage: doc.get(),\n user,\n };\n};\n","import type { JsonSchemaProducer } from \"../types\";\n\nexport const getJsonSchemaProducer = (schema: unknown): JsonSchemaProducer | null => {\n const jsonSchema = (schema as { \"~standard\"?: { jsonSchema?: JsonSchemaProducer } })?.[\n \"~standard\"\n ]?.jsonSchema;\n\n if (!jsonSchema || typeof jsonSchema.input !== \"function\") return null;\n\n return jsonSchema;\n};\n","export class JsonSchemaError extends Error {\n constructor() {\n super(\n \"Schema must implement Standard Schema and Standard JSON Schema on the same object (e.g. Zod 4.2+ or ArkType).\",\n );\n this.name = \"JsonSchemaError\";\n }\n}\n","import type { TreatyProcedureLike } from \"@pluv/types\";\nimport type { JsonSchemaProducer } from \"../types\";\nimport { getJsonSchemaProducer } from \"./getJsonSchemaProducer\";\nimport { JsonSchemaError } from \"./JsonSchemaError\";\n\nexport const assertResolvedProcedure = (\n name: string,\n kind: \"presence\" | \"storage\",\n procedure: TreatyProcedureLike,\n): void => {\n if (typeof procedure.apply !== \"function\" || !procedure.config.resolve) {\n throw new Error(`Treaty ${kind} procedure \"${name}\" is missing resolve`);\n }\n};\n\nexport const assertSerializingSchema = (schema: unknown): JsonSchemaProducer => {\n const producer = getJsonSchemaProducer(schema);\n\n if (!producer) throw new JsonSchemaError();\n\n return producer;\n};\n\nexport const assertOutputJsonSchema = (schema: unknown): JsonSchemaProducer => {\n const producer = assertSerializingSchema(schema);\n\n if (typeof producer.output !== \"function\") throw new JsonSchemaError();\n\n return producer;\n};\n","const asyncFunction = (async () => undefined).constructor;\n\nexport const isAsyncFunction = (value: (...args: never[]) => unknown): boolean =>\n value.constructor === asyncFunction;\n","import type { JsonSchemaMethod, JsonSchemaProducer } from \"../types\";\nimport { JsonSchemaError } from \"./JsonSchemaError\";\n\nconst JSON_SCHEMA_TARGET = \"draft-2020-12\";\n\nconst emitJsonSchema = (produce: JsonSchemaMethod | undefined): unknown => {\n if (typeof produce !== \"function\") throw new JsonSchemaError();\n\n return produce({ target: JSON_SCHEMA_TARGET });\n};\n\nexport const toInputJsonSchema = (schema: JsonSchemaProducer): unknown => {\n return emitJsonSchema(schema.input);\n};\n\nexport const toOutputJsonSchema = (schema: JsonSchemaProducer): unknown => {\n return emitJsonSchema(schema.output);\n};\n","import type { OperatorUser, StandardSchemaV1, TreatyProcedureLike } from \"@pluv/types\";\nimport { parseProcedureInput } from \"./parseProcedureInput\";\nimport { toStorageResolverContext } from \"./toStorageResolverContext\";\nimport { isAsyncFunction } from \"./utils\";\nimport type {\n StoragePrepareContext,\n StorageResolverContext,\n TreatyResolverDoc,\n TreatyStorageResolveOptions,\n} from \"./types\";\n\ndeclare const storageUnprepared: unique symbol;\n\ntype StorageUnprepared = typeof storageUnprepared;\n\ntype StoragePrepared<TPrepared> = [TPrepared] extends [StorageUnprepared] ? undefined : TPrepared;\n\ntype StoragePrepareFn<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TPrepared,\n> = (\n data: TInput,\n context: StoragePrepareContext<TUser, TPresence>,\n) => TPrepared | Promise<TPrepared>;\n\ntype StorageResolveFn<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n TPrepared,\n> = (\n data: TInput,\n context: StorageResolverContext<TUser, TJson, TNative, TPresence>,\n prepared: StoragePrepared<TPrepared>,\n) => undefined;\n\ntype StorageProcedureConfig<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n TPrepared,\n> = {\n input?: StandardSchemaV1<unknown, TInput> | null;\n prepare?: StoragePrepareFn<TInput, TUser, TPresence, TPrepared> | null;\n resolve?: StorageResolveFn<TInput, TUser, TPresence, TJson, TNative, TPrepared> | null;\n transact?: boolean | null;\n};\n\ntype StorageProcedureDefs<\n TInput extends Record<string, any>,\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n TPrepared,\n> = {\n input: StandardSchemaV1<unknown, TInput> | null;\n prepare: StoragePrepareFn<TInput, TUser, TPresence, TPrepared> | null;\n resolve: StorageResolveFn<TInput, TUser, TPresence, TJson, TNative, TPrepared> | null;\n transact: boolean;\n};\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === \"function\";\n\nconst toStoragePrepareContext = <\n TUser extends { id: string },\n TPresence extends Record<string, any>,\n>(params: {\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n}): StoragePrepareContext<TUser, TPresence> => {\n return {\n operator: params.operator ?? null,\n presence: JSON.parse(JSON.stringify(params.presence ?? {})),\n user: params.user,\n };\n};\n\nexport class TreatyStorageProcedure<\n TUser extends { id: string },\n TJson extends Record<string, any>,\n TNative extends Record<string, any>,\n TPresence extends Record<string, any> = {},\n TInput extends Record<string, any> = {},\n TPrepared = StorageUnprepared,\n TFilled extends \"input\" | \"prepare\" | \"resolve\" | \"\" = \"\",\n> implements TreatyProcedureLike<\"storage\", TInput> {\n public readonly kind = \"storage\" as const;\n\n public readonly prepared: [TPrepared] extends [StorageUnprepared] ? false : true;\n\n private readonly _defs: StorageProcedureDefs<\n TInput,\n TUser,\n TPresence,\n TJson,\n TNative,\n TPrepared\n >;\n\n public get config(): TreatyProcedureLike<\"storage\", TInput>[\"config\"] {\n return this._defs;\n }\n\n constructor(\n config: StorageProcedureConfig<TInput, TUser, TPresence, TJson, TNative, TPrepared> = {},\n ) {\n const prepare = config.prepare ?? null;\n\n this.prepared = (prepare !== null) as [TPrepared] extends [StorageUnprepared]\n ? false\n : true;\n this._defs = {\n input: config.input ?? null,\n prepare,\n resolve: config.resolve ?? null,\n transact: config.transact ?? true,\n };\n }\n\n public async load(\n data: unknown,\n params: {\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n },\n ): Promise<{ input: TInput; prepared: StoragePrepared<TPrepared> }> {\n const input = parseProcedureInput(this._defs.input, data);\n\n if (!this._defs.prepare)\n return { input, prepared: undefined as StoragePrepared<TPrepared> };\n\n return {\n input,\n prepared: (await this._defs.prepare(\n input,\n toStoragePrepareContext(params),\n )) as StoragePrepared<TPrepared>,\n };\n }\n\n public apply(\n data: unknown,\n params: {\n doc: TreatyResolverDoc<TJson, TNative>;\n operator?: OperatorUser | null;\n presence?: TPresence | null;\n user: TUser;\n },\n prepared?: unknown,\n ): void {\n if (!this._defs.resolve) {\n throw new Error(\"Treaty storage procedure is missing resolve\");\n }\n\n if (isAsyncFunction(this._defs.resolve)) {\n throw new Error(\"Treaty storage procedure resolve must be synchronous\");\n }\n\n // `load` already parsed a prepared procedure. Parsing again would rerun\n // defaults and transforms, so `resolve` would see a different value.\n const parsed = this.prepared\n ? (data as TInput)\n : parseProcedureInput(this._defs.input, data);\n const result: unknown = this._defs.resolve(\n parsed,\n toStorageResolverContext(params),\n prepared as StoragePrepared<TPrepared>,\n );\n\n if (isThenable(result)) {\n // `resolve` has to run before a returned promise is visible.\n // Swallow it so the rejection does not surface as unhandled.\n void Promise.resolve(result).catch(() => undefined);\n\n throw new Error(\"Treaty storage procedure resolve must be synchronous\");\n }\n }\n\n public input<TData extends Record<string, any>>(\n input: StandardSchemaV1<unknown, TData>,\n ): Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TData,\n TPrepared,\n TFilled | \"input\"\n >,\n TFilled | \"input\"\n > {\n return new TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TData,\n TPrepared,\n TFilled | \"input\"\n >({\n input,\n prepare: this._defs.prepare as StoragePrepareFn<\n TData,\n TUser,\n TPresence,\n TPrepared\n > | null,\n transact: this._defs.transact,\n }) as Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TData,\n TPrepared,\n TFilled | \"input\"\n >,\n TFilled | \"input\"\n >;\n }\n\n public prepare<TResult>(\n loader: StoragePrepareFn<TInput, TUser, TPresence, TResult>,\n ): Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TResult,\n TFilled | \"prepare\"\n >,\n TFilled | \"prepare\" | \"input\"\n > {\n if (this._defs.prepare) throw new Error(\"Prepare was already defined for this procedure\");\n\n return new TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TResult,\n TFilled | \"prepare\"\n >({\n input: this._defs.input,\n prepare: loader,\n transact: this._defs.transact,\n }) as Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TResult,\n TFilled | \"prepare\"\n >,\n TFilled | \"prepare\" | \"input\"\n >;\n }\n\n public resolve(\n resolver: (\n data: TInput,\n context: StorageResolverContext<TUser, TJson, TNative, TPresence>,\n prepared: StoragePrepared<TPrepared>,\n ) => undefined,\n options: TreatyStorageResolveOptions = {},\n ): Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TPrepared,\n TFilled | \"input\" | \"prepare\" | \"resolve\"\n >,\n TFilled | \"input\" | \"prepare\" | \"resolve\"\n > {\n if (this._defs.resolve) throw new Error(\"Resolve was already defined for this procedure\");\n\n return new TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TPrepared,\n TFilled | \"input\" | \"prepare\" | \"resolve\"\n >({\n input: this._defs.input,\n prepare: this._defs.prepare,\n resolve: resolver,\n transact: options.transact ?? true,\n }) as Omit<\n TreatyStorageProcedure<\n TUser,\n TJson,\n TNative,\n TPresence,\n TInput,\n TPrepared,\n TFilled | \"input\" | \"prepare\" | \"resolve\"\n >,\n TFilled | \"input\" | \"prepare\" | \"resolve\"\n >;\n }\n}\n","import type { AbstractCrdtDocFactory } from \"@pluv/crdt\";\nimport type {\n BaseUser,\n StandardSchemaV1,\n TreatyLike,\n TreatyProcedureInputsJson,\n TreatyProcedureLike,\n TreatyProceduresJson,\n} from \"@pluv/types\";\nimport { TreatyPresenceProcedure } from \"./TreatyPresenceProcedure\";\nimport { TreatyStorageProcedure } from \"./TreatyStorageProcedure\";\nimport type {\n InferTreatyPresenceOutput,\n InferTreatyStorageJson,\n InferTreatyStorageNative,\n InferTreatyUserOutput,\n} from \"./types\";\nimport {\n assertOutputJsonSchema,\n assertResolvedProcedure,\n assertSerializingSchema,\n toInputJsonSchema,\n toOutputJsonSchema,\n} from \"./utils\";\n\ntype PartitionPresence<TEvents extends Record<string, TreatyProcedureLike>> = {\n [\n K in keyof TEvents as TEvents[K] extends TreatyProcedureLike<\"presence\"> ? K : never\n ]: TEvents[K];\n};\n\ntype PartitionStorage<TEvents extends Record<string, TreatyProcedureLike>> = {\n [\n K in keyof TEvents as TEvents[K] extends TreatyProcedureLike<\"storage\"> ? K : never\n ]: TEvents[K];\n};\n\ntype HasPresenceSchema<TPresence> = [TPresence] extends [undefined]\n ? false\n : [TPresence] extends [never]\n ? false\n : true;\n\ntype HasStorageSchema<TStorage> = [TStorage] extends [undefined]\n ? false\n : [TStorage] extends [never]\n ? false\n : TStorage extends AbstractCrdtDocFactory<any, any, any, any>\n ? true\n : false;\n\ntype ResolverJson<TStorage> = [InferTreatyStorageJson<TStorage>] extends [never]\n ? {}\n : InferTreatyStorageJson<TStorage>;\n\ntype ResolverNative<TStorage> = [InferTreatyStorageNative<TStorage>] extends [never]\n ? {}\n : InferTreatyStorageNative<TStorage>;\n\ntype TreatyProcedureAccessors<\n TUserSchema extends StandardSchemaV1<unknown, BaseUser>,\n TPresenceSchema,\n TStorage,\n> = (HasPresenceSchema<TPresenceSchema> extends true\n ? {\n presence: TreatyPresenceProcedure<\n InferTreatyUserOutput<TUserSchema>,\n InferTreatyPresenceOutput<TPresenceSchema>,\n ResolverJson<TStorage>,\n ResolverNative<TStorage>\n >;\n }\n : {}) &\n (HasStorageSchema<TStorage> extends true\n ? {\n storage: TreatyStorageProcedure<\n InferTreatyUserOutput<TUserSchema>,\n ResolverJson<TStorage>,\n ResolverNative<TStorage>,\n InferTreatyPresenceOutput<TPresenceSchema>\n >;\n }\n : {});\n\ntype RouterEventMap<TPresenceSchema, TStorage> = Record<\n string,\n | (HasPresenceSchema<TPresenceSchema> extends true ? TreatyProcedureLike<\"presence\"> : never)\n | (HasStorageSchema<TStorage> extends true ? TreatyProcedureLike<\"storage\"> : never)\n>;\n\ntype MergeTreatyProcedureMaps<\n TTreaties extends readonly Treaty<any, any, any, any, any>[],\n TPresence extends Record<string, any>,\n TStorage extends Record<string, any>,\n> = TTreaties extends readonly [\n infer IHead extends Treaty<any, any, any, any, any>,\n ...infer ITail extends Treaty<any, any, any, any, any>[],\n]\n ? MergeTreatyProcedureMaps<\n ITail,\n TPresence & IHead[\"_defs\"][\"procedures\"][\"presence\"],\n TStorage & IHead[\"_defs\"][\"procedures\"][\"storage\"]\n >\n : { presence: TPresence; storage: TStorage };\n\nexport type CreateTreatyConfig<\n TUserSchema extends StandardSchemaV1<unknown, BaseUser>,\n TPresenceSchema extends StandardSchemaV1<any, any> | undefined = undefined,\n TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined = undefined,\n> = {\n user: TUserSchema;\n presence?: TPresenceSchema;\n storage?: TStorage;\n};\n\nexport class Treaty<\n TUserSchema extends StandardSchemaV1<unknown, BaseUser> = StandardSchemaV1<unknown, BaseUser>,\n TPresenceSchema extends StandardSchemaV1<any, any> | undefined =\n | StandardSchemaV1<any, any>\n | undefined,\n TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined =\n | AbstractCrdtDocFactory<any, any, any, any>\n | undefined,\n TPresenceProcedures extends Record<string, TreatyProcedureLike<\"presence\">> = {},\n TStorageProcedures extends Record<string, TreatyProcedureLike<\"storage\">> = {},\n> implements TreatyLike {\n public readonly user: TUserSchema;\n public readonly presence: TPresenceSchema;\n public readonly storage: TStorage;\n\n public readonly _defs: {\n user: TUserSchema;\n presence: TPresenceSchema;\n storage: TStorage;\n procedures: {\n presence: TPresenceProcedures;\n storage: TStorageProcedures;\n };\n };\n\n public get procedure(): TreatyProcedureAccessors<TUserSchema, TPresenceSchema, TStorage> {\n const accessors = {} as TreatyProcedureAccessors<TUserSchema, TPresenceSchema, TStorage>;\n\n if (this.presence) {\n (accessors as { presence: TreatyPresenceProcedure<any, any, any, any> }).presence =\n new TreatyPresenceProcedure();\n }\n\n if (this.storage) {\n (accessors as { storage: TreatyStorageProcedure<any, any, any, any> }).storage =\n new TreatyStorageProcedure();\n }\n\n return accessors;\n }\n\n constructor(\n config: CreateTreatyConfig<TUserSchema, TPresenceSchema, TStorage>,\n procedures: {\n presence: TPresenceProcedures;\n storage: TStorageProcedures;\n } = { presence: {} as TPresenceProcedures, storage: {} as TStorageProcedures },\n ) {\n this.user = config.user;\n this.presence = config.presence as TPresenceSchema;\n this.storage = config.storage as TStorage;\n this._defs = {\n user: this.user,\n presence: this.presence,\n storage: this.storage,\n procedures,\n };\n }\n\n public mergeRouters<\n TTreaties extends Treaty<TUserSchema, TPresenceSchema, TStorage, any, any>[],\n >(\n ...treaties: TTreaties\n ): Treaty<\n TUserSchema,\n TPresenceSchema,\n TStorage,\n MergeTreatyProcedureMaps<TTreaties, TPresenceProcedures, TStorageProcedures>[\"presence\"],\n MergeTreatyProcedureMaps<TTreaties, TPresenceProcedures, TStorageProcedures>[\"storage\"]\n > {\n const presence = Object.create(null) as Record<string, TreatyProcedureLike<\"presence\">>;\n const storage = Object.create(null) as Record<string, TreatyProcedureLike<\"storage\">>;\n\n for (const treaty of [this, ...treaties]) {\n for (const name of Object.keys(treaty._defs.procedures.presence)) {\n if (Object.hasOwn(presence, name)) {\n throw new Error(\n `Duplicate presence procedure \"${name}\" when merging treaty routers`,\n );\n }\n\n presence[name] = treaty._defs.procedures.presence[name];\n }\n\n for (const name of Object.keys(treaty._defs.procedures.storage)) {\n if (Object.hasOwn(storage, name)) {\n throw new Error(\n `Duplicate storage procedure \"${name}\" when merging treaty routers`,\n );\n }\n\n storage[name] = treaty._defs.procedures.storage[name];\n }\n }\n\n return new Treaty(\n { user: this.user, presence: this.presence, storage: this.storage },\n { presence, storage },\n ) as any;\n }\n\n public router<TEvents extends RouterEventMap<TPresenceSchema, TStorage>>(\n events: TEvents,\n ): Treaty<\n TUserSchema,\n TPresenceSchema,\n TStorage,\n TPresenceProcedures & PartitionPresence<TEvents>,\n TStorageProcedures & PartitionStorage<TEvents>\n > {\n const presence = Object.assign(\n Object.create(null),\n this._defs.procedures.presence,\n ) as TPresenceProcedures & PartitionPresence<TEvents>;\n const storage = Object.assign(\n Object.create(null),\n this._defs.procedures.storage,\n ) as TStorageProcedures & PartitionStorage<TEvents>;\n\n Object.entries(events).forEach(([name, procedure]) => {\n if (procedure.kind === \"presence\") {\n if (Object.hasOwn(presence, name)) {\n throw new Error(`Duplicate presence procedure \"${name}\"`);\n }\n\n assertResolvedProcedure(name, \"presence\", procedure);\n (presence as Record<string, TreatyProcedureLike<\"presence\">>)[name] = procedure;\n return;\n }\n\n if (procedure.kind === \"storage\") {\n if (Object.hasOwn(storage, name)) {\n throw new Error(`Duplicate storage procedure \"${name}\"`);\n }\n\n assertResolvedProcedure(name, \"storage\", procedure);\n (storage as Record<string, TreatyProcedureLike<\"storage\">>)[name] = procedure;\n return;\n }\n\n throw new Error(`Unknown treaty procedure kind for \"${name}\"`);\n });\n\n return new Treaty(\n { user: this.user, presence: this.presence, storage: this.storage },\n { presence, storage },\n );\n }\n\n public toUserJson(): unknown {\n return toOutputJsonSchema(assertOutputJsonSchema(this.user));\n }\n\n public toPresenceJson(): unknown {\n if (!this.presence) {\n throw new Error(\"Treaty has no presence schema\");\n }\n\n return toOutputJsonSchema(assertOutputJsonSchema(this.presence));\n }\n\n public toStorageJson(): unknown {\n const storage = this.storage as { toJSON?: () => unknown } | undefined;\n\n if (!storage || typeof storage.toJSON !== \"function\") {\n throw new Error(\"Treaty has no storage schema\");\n }\n\n return storage.toJSON();\n }\n\n public toProceduresJson(): TreatyProceduresJson<TPresenceProcedures, TStorageProcedures> {\n return {\n presence: this.toProcedureInputs(this._defs.procedures.presence),\n storage: this.toProcedureInputs(this._defs.procedures.storage),\n };\n }\n\n private toProcedureInputs<TProcedures extends Record<string, TreatyProcedureLike>>(\n procedures: TProcedures,\n ): TreatyProcedureInputsJson<TProcedures> {\n return Object.entries(procedures).reduce<TreatyProcedureInputsJson<TProcedures>>(\n (acc, [name, procedure]) => {\n const input = procedure.config.input;\n\n acc[name as keyof TProcedures] = {\n input: input ? toInputJsonSchema(assertSerializingSchema(input)) : null,\n };\n\n return acc;\n },\n Object.create(null),\n );\n }\n}\n","import type { AbstractCrdtDocFactory } from \"@pluv/crdt\";\nimport type { BaseUser, StandardSchemaV1 } from \"@pluv/types\";\nimport { Treaty, type CreateTreatyConfig } from \"./Treaty\";\nimport { assertOutputJsonSchema } from \"./utils\";\n\nexport const createTreaty = <\n TUserSchema extends StandardSchemaV1<unknown, BaseUser>,\n TPresenceSchema extends StandardSchemaV1<any, any> | undefined = undefined,\n TStorage extends AbstractCrdtDocFactory<any, any, any, any> | undefined = undefined,\n>(\n config: CreateTreatyConfig<TUserSchema, TPresenceSchema, TStorage>,\n): Treaty<TUserSchema, TPresenceSchema, TStorage> => {\n assertOutputJsonSchema(config.user);\n\n if (config.presence) {\n assertOutputJsonSchema(config.presence);\n }\n\n return new Treaty(config);\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,48 @@
1
1
  {
2
- "name": "@pluv/treaty",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@pluv/treaty",
3
+ "version": "5.2.3",
4
+ "description": "isomorphic schema and procedure contract for @pluv/io",
5
+ "author": {
6
+ "email": "david@pluv.io",
7
+ "name": "i3dly",
8
+ "url": "https://github.com/i3dly"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://github.com/pluv-io/pluv",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/pluv-io/pluv.git",
15
+ "directory": "packages/treaty"
16
+ },
17
+ "type": "module",
18
+ "types": "./dist/index.d.mts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "build": "tsdown",
27
+ "dev": "tsdown --watch",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
32
+ },
33
+ "dependencies": {
34
+ "@pluv/crdt": "workspace:^",
35
+ "@pluv/types": "workspace:^"
36
+ },
37
+ "devDependencies": {
38
+ "@pluv/tsconfig": "workspace:^",
39
+ "tsdown": "^0.23.2",
40
+ "typescript": "7.1.0-beta",
41
+ "vitest": "^5.0.5",
42
+ "zod": "^4.6.7"
43
+ },
44
+ "exports": {
45
+ ".": "./dist/index.mjs",
46
+ "./*": "./*"
47
+ }
48
+ }