@kubun/protocol 0.4.1 → 0.5.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/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { AnyClientMessageOf, AnyServerMessageOf, ClientTransportOf, ServerTransportOf } from '@enkaku/protocol';
2
2
  import type { DocumentProtocol } from './services/document.js';
3
3
  import type { GraphProtocol } from './services/graph.js';
4
+ import type { SyncProtocol } from './services/sync.js';
4
5
  export * from './models/cluster.js';
5
6
  export * from './models/document.js';
6
7
  export * from './models/graph.js';
@@ -8,10 +9,10 @@ export * from './models/json-schema.js';
8
9
  export * from './models/value.js';
9
10
  export * from './services/document.js';
10
11
  export * from './services/graph.js';
12
+ export * from './services/sync.js';
11
13
  export * from './types.js';
12
- export type Protocol = DocumentProtocol & GraphProtocol;
14
+ export type Protocol = DocumentProtocol & GraphProtocol & SyncProtocol;
13
15
  export type ClientMessage = AnyClientMessageOf<Protocol>;
14
16
  export type ServerMessage = AnyServerMessageOf<Protocol>;
15
17
  export type ClientTransport = ClientTransportOf<Protocol>;
16
18
  export type ServerTransport = ServerTransportOf<Protocol>;
17
- //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -1,8 +1 @@
1
- export * from './models/cluster.js';
2
- export * from './models/document.js';
3
- export * from './models/graph.js';
4
- export * from './models/json-schema.js';
5
- export * from './models/value.js';
6
- export * from './services/document.js';
7
- export * from './services/graph.js';
8
- export * from './types.js';
1
+ export*from"./models/cluster.js";export*from"./models/document.js";export*from"./models/graph.js";export*from"./models/json-schema.js";export*from"./models/value.js";export*from"./services/document.js";export*from"./services/graph.js";export*from"./services/sync.js";export*from"./types.js";
@@ -329,6 +329,9 @@ export declare const clusterModel: {
329
329
  readonly type: "string";
330
330
  readonly const: "account";
331
331
  };
332
+ readonly searchable: {
333
+ readonly type: "boolean";
334
+ };
332
335
  };
333
336
  readonly required: readonly ["type"];
334
337
  readonly additionalProperties: false;
@@ -339,6 +342,9 @@ export declare const clusterModel: {
339
342
  readonly type: "string";
340
343
  readonly const: "attachment";
341
344
  };
345
+ readonly searchable: {
346
+ readonly type: "boolean";
347
+ };
342
348
  };
343
349
  readonly required: readonly ["type"];
344
350
  readonly additionalProperties: false;
@@ -356,6 +362,9 @@ export declare const clusterModel: {
356
362
  readonly type: "null";
357
363
  }];
358
364
  };
365
+ readonly searchable: {
366
+ readonly type: "boolean";
367
+ };
359
368
  };
360
369
  readonly required: readonly ["type", "model"];
361
370
  readonly additionalProperties: false;
@@ -679,6 +688,9 @@ export declare const clusterModel: {
679
688
  readonly type: "string";
680
689
  readonly const: "account";
681
690
  };
691
+ readonly searchable: {
692
+ readonly type: "boolean";
693
+ };
682
694
  };
683
695
  readonly required: readonly ["type"];
684
696
  readonly additionalProperties: false;
@@ -689,6 +701,9 @@ export declare const clusterModel: {
689
701
  readonly type: "string";
690
702
  readonly const: "attachment";
691
703
  };
704
+ readonly searchable: {
705
+ readonly type: "boolean";
706
+ };
692
707
  };
693
708
  readonly required: readonly ["type"];
694
709
  readonly additionalProperties: false;
@@ -706,6 +721,9 @@ export declare const clusterModel: {
706
721
  readonly type: "null";
707
722
  }];
708
723
  };
724
+ readonly searchable: {
725
+ readonly type: "boolean";
726
+ };
709
727
  };
710
728
  readonly required: readonly ["type", "model"];
711
729
  readonly additionalProperties: false;
@@ -1035,6 +1053,9 @@ export declare const clusterModel: {
1035
1053
  readonly type: "string";
1036
1054
  readonly const: "account";
1037
1055
  };
1056
+ readonly searchable: {
1057
+ readonly type: "boolean";
1058
+ };
1038
1059
  };
1039
1060
  readonly required: readonly ["type"];
1040
1061
  readonly additionalProperties: false;
@@ -1045,6 +1066,9 @@ export declare const clusterModel: {
1045
1066
  readonly type: "string";
1046
1067
  readonly const: "attachment";
1047
1068
  };
1069
+ readonly searchable: {
1070
+ readonly type: "boolean";
1071
+ };
1048
1072
  };
1049
1073
  readonly required: readonly ["type"];
1050
1074
  readonly additionalProperties: false;
@@ -1062,6 +1086,9 @@ export declare const clusterModel: {
1062
1086
  readonly type: "null";
1063
1087
  }];
1064
1088
  };
1089
+ readonly searchable: {
1090
+ readonly type: "boolean";
1091
+ };
1065
1092
  };
1066
1093
  readonly required: readonly ["type", "model"];
1067
1094
  readonly additionalProperties: false;
@@ -1169,10 +1196,13 @@ export declare const validateClusterModel: import("@enkaku/schema").Validator<{
1169
1196
  };
1170
1197
  fieldsMeta: {
1171
1198
  [x: string]: {
1199
+ searchable?: boolean | undefined;
1172
1200
  type: "account";
1173
1201
  } | {
1202
+ searchable?: boolean | undefined;
1174
1203
  type: "attachment";
1175
1204
  } | {
1205
+ searchable?: boolean | undefined;
1176
1206
  type: "document";
1177
1207
  model: string | null;
1178
1208
  };
@@ -1257,10 +1287,13 @@ export declare const validateClusterModel: import("@enkaku/schema").Validator<{
1257
1287
  };
1258
1288
  fieldsMeta: {
1259
1289
  [x: string]: {
1290
+ searchable?: boolean | undefined;
1260
1291
  type: "account";
1261
1292
  } | {
1293
+ searchable?: boolean | undefined;
1262
1294
  type: "attachment";
1263
1295
  } | {
1296
+ searchable?: boolean | undefined;
1264
1297
  type: "document";
1265
1298
  model: string | null;
1266
1299
  };
@@ -1345,10 +1378,13 @@ export declare const validateClusterModel: import("@enkaku/schema").Validator<{
1345
1378
  };
1346
1379
  fieldsMeta: {
1347
1380
  [x: string]: {
1381
+ searchable?: boolean | undefined;
1348
1382
  type: "account";
1349
1383
  } | {
1384
+ searchable?: boolean | undefined;
1350
1385
  type: "attachment";
1351
1386
  } | {
1387
+ searchable?: boolean | undefined;
1352
1388
  type: "document";
1353
1389
  model: string | null;
1354
1390
  };
@@ -1363,6 +1399,7 @@ export declare const validateClusterModel: import("@enkaku/schema").Validator<{
1363
1399
  }>;
1364
1400
  export declare function verifyCluster(cluster: ClusterModel): DocumentModelsRecord;
1365
1401
  export type ClusterBuilderParams = {
1402
+ externalModels?: Record<string, DocumentModel>;
1366
1403
  logger?: Logger;
1367
1404
  };
1368
1405
  export declare class ClusterBuilder {
@@ -1375,4 +1412,3 @@ export declare class ClusterBuilder {
1375
1412
  add(inputModel: DocumentModelInput): DocumentModelID;
1376
1413
  addAll(models: Array<DocumentModelInput>): Array<DocumentModelID>;
1377
1414
  }
1378
- //# sourceMappingURL=cluster.d.ts.map
@@ -1,132 +1 @@
1
- import { toB64 } from '@enkaku/codec';
2
- import { assertType, createValidator } from '@enkaku/schema';
3
- import { DocumentModelID, digestJSON } from '@kubun/id';
4
- import { getKubunLogger } from '@kubun/logger';
5
- import { DocumentModelNormalizer, documentModelsCluster } from './document.js';
6
- import { binaryStringValue } from './value.js';
7
- export const clusterModel = {
8
- $id: 'urn:kubun:protocol:model:cluster',
9
- type: 'object',
10
- properties: {
11
- digest: binaryStringValue,
12
- models: documentModelsCluster,
13
- record: {
14
- type: 'object',
15
- patternProperties: {
16
- '^k[0-9a-z]{56}$': {
17
- type: 'integer',
18
- minimum: 0
19
- }
20
- },
21
- additionalProperties: false
22
- }
23
- },
24
- required: [
25
- 'digest',
26
- 'models',
27
- 'record'
28
- ],
29
- additionalProperties: false
30
- };
31
- export const validateClusterModel = createValidator(clusterModel);
32
- export function verifyCluster(cluster) {
33
- assertType(validateClusterModel, cluster);
34
- const digest = digestJSON(cluster.models);
35
- if (cluster.digest !== toB64(digest)) {
36
- throw new Error('Invalid cluster: digest mismatch');
37
- }
38
- const recordEntries = Object.entries(cluster.record);
39
- if (recordEntries.length !== cluster.models.length) {
40
- throw new Error('Invalid cluster: record length mismatch');
41
- }
42
- const record = {};
43
- for (const [id, index] of recordEntries){
44
- const expectedID = new DocumentModelID(digest, index).toString();
45
- if (id !== expectedID) {
46
- throw new Error(`Invalid cluster: record key mismatch, expected ${expectedID}, got ${id}`);
47
- }
48
- const model = cluster.models[index];
49
- if (model == null) {
50
- throw new Error(`Invalid cluster: missing model at index ${index}`);
51
- }
52
- record[id] = model;
53
- }
54
- return record;
55
- }
56
- export class ClusterBuilder {
57
- #cluster = [];
58
- #logger;
59
- constructor(params = {}){
60
- this.#logger = params.logger ?? getKubunLogger('protocol');
61
- }
62
- get cluster() {
63
- return this.#cluster;
64
- }
65
- get length() {
66
- return this.#cluster.length;
67
- }
68
- build() {
69
- const models = this.#cluster;
70
- if (models.length === 0) {
71
- throw new Error('Cluster is empty');
72
- }
73
- const digest = digestJSON(models);
74
- const record = {};
75
- for(let index = 0; index < models.length; index++){
76
- const id = new DocumentModelID(digest, index);
77
- record[id.toString()] = index;
78
- }
79
- return {
80
- digest: toB64(digest),
81
- models,
82
- record
83
- };
84
- }
85
- get(id) {
86
- let index;
87
- if (typeof id === 'number') {
88
- index = id;
89
- } else if (typeof id === 'string' && id[0] === '#') {
90
- index = Number.parseInt(id.slice(1), 10);
91
- if (Number.isNaN(index)) {
92
- throw new Error(`Invalid DocumentModelID: ${id}`);
93
- }
94
- } else {
95
- const docID = typeof id === 'string' ? DocumentModelID.fromString(id) : id;
96
- if (!docID.isLocal) {
97
- throw new Error('Invalid DocumentModelID to access model in cluster: must be a local ID');
98
- }
99
- index = docID.index;
100
- }
101
- const model = this.#cluster[index];
102
- if (model == null) {
103
- throw new RangeError(`Invalid cluster index: ${index}`);
104
- }
105
- return model;
106
- }
107
- add(inputModel) {
108
- const interfaceIDs = inputModel.interfaces ?? [];
109
- const normalizedInterfaceIDs = interfaceIDs.map((id)=>{
110
- if (id.startsWith('#')) {
111
- const index = Number.parseInt(id.slice(1), 10);
112
- if (Number.isNaN(index)) {
113
- throw new Error(`Invalid DocumentModelID: ${id}`);
114
- }
115
- return DocumentModelID.local(index).toString();
116
- }
117
- return id;
118
- });
119
- const model = new DocumentModelNormalizer({
120
- inputModel,
121
- interfaceModels: normalizedInterfaceIDs.map((id)=>this.get(id)),
122
- logger: this.#logger,
123
- normalizedInterfaceIDs
124
- }).toDocumentModel();
125
- const index = this.#cluster.length;
126
- this.#cluster.push(model);
127
- return DocumentModelID.local(index);
128
- }
129
- addAll(models) {
130
- return models.map((input)=>this.add(input));
131
- }
132
- }
1
+ import{toB64 as e}from"@enkaku/codec";import{assertType as t,createValidator as r}from"@enkaku/schema";import{DocumentModelID as l,digestJSON as o}from"@kubun/id";import{getKubunLogger as i}from"@kubun/logger";import{DocumentModelNormalizer as s,documentModelsCluster as n}from"./document.js";import{binaryStringValue as d}from"./value.js";export const clusterModel={$id:"urn:kubun:protocol:model:cluster",type:"object",properties:{digest:d,models:n,record:{type:"object",patternProperties:{"^k[0-9a-z]{56}$":{type:"integer",minimum:0}},additionalProperties:!1}},required:["digest","models","record"],additionalProperties:!1};export const validateClusterModel=r(clusterModel);export function verifyCluster(r){t(validateClusterModel,r);let i=o(r.models);if(r.digest!==e(i))throw Error("Invalid cluster: digest mismatch");let s=Object.entries(r.record);if(s.length!==r.models.length)throw Error("Invalid cluster: record length mismatch");let n={};for(let[e,t]of s){let o=new l(i,t).toString();if(e!==o)throw Error(`Invalid cluster: record key mismatch, expected ${o}, got ${e}`);let s=r.models[t];if(null==s)throw Error(`Invalid cluster: missing model at index ${t}`);n[e]=s}return n}export class ClusterBuilder{#e=[];#t;#r;constructor(e={}){this.#t=e.externalModels??{},this.#r=e.logger??i("protocol")}get cluster(){return this.#e}get length(){return this.#e.length}build(){let t=this.#e;if(0===t.length)throw Error("Cluster is empty");let r=o(t),i={};for(let e=0;e<t.length;e++)i[new l(r,e).toString()]=e;return{digest:e(r),models:t,record:i}}get(e){let t;if("number"==typeof e)t=e;else if("string"==typeof e&&"#"===e[0]){if(Number.isNaN(t=Number.parseInt(e.slice(1),10)))throw Error(`Invalid DocumentModelID: ${e}`)}else{let r="string"==typeof e?l.fromString(e):e;if(!r.isLocal){let t="string"==typeof e?e:e.toString(),r=this.#t[t];if(null!=r)return r;throw Error(`External model not found: ${t}`)}t=r.index}let r=this.#e[t];if(null==r)throw RangeError(`Invalid cluster index: ${t}`);return r}add(e){let t=(e.interfaces??[]).map(e=>{if(e.startsWith("#")){let t=Number.parseInt(e.slice(1),10);if(Number.isNaN(t))throw Error(`Invalid DocumentModelID: ${e}`);return l.local(t).toString()}return e}),r=new s({inputModel:e,interfaceModels:t.map(e=>this.get(e)),logger:this.#r,normalizedInterfaceIDs:t}).toDocumentModel(),o=this.#e.length;return this.#e.push(r),l.local(o)}addAll(e){return e.map(e=>this.add(e))}}