@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 +3 -2
- package/lib/index.js +1 -8
- package/lib/models/cluster.d.ts +37 -1
- package/lib/models/cluster.js +1 -132
- package/lib/models/document.d.ts +153 -1
- package/lib/models/document.js +1 -525
- package/lib/models/graph.d.ts +0 -1
- package/lib/models/graph.js +1 -52
- package/lib/models/json-schema.d.ts +0 -1
- package/lib/models/json-schema.js +1 -320
- package/lib/models/value.d.ts +0 -1
- package/lib/models/value.js +1 -16
- package/lib/services/document.d.ts +0 -1
- package/lib/services/document.js +1 -50
- package/lib/services/graph.d.ts +250 -1
- package/lib/services/graph.js +1 -240
- package/lib/services/sync.d.ts +182 -0
- package/lib/services/sync.js +1 -0
- package/lib/types.d.ts +0 -1
- package/lib/types.js +1 -1
- package/package.json +6 -6
- package/lib/index.d.ts.map +0 -1
- package/lib/models/cluster.d.ts.map +0 -1
- package/lib/models/document.d.ts.map +0 -1
- package/lib/models/graph.d.ts.map +0 -1
- package/lib/models/json-schema.d.ts.map +0 -1
- package/lib/models/value.d.ts.map +0 -1
- package/lib/services/document.d.ts.map +0 -1
- package/lib/services/graph.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
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
|
|
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";
|
package/lib/models/cluster.d.ts
CHANGED
|
@@ -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
|
package/lib/models/cluster.js
CHANGED
|
@@ -1,132 +1 @@
|
|
|
1
|
-
import {
|
|
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))}}
|