@rljson/rljson 0.0.12 → 0.0.14

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/dist/example.d.ts CHANGED
@@ -1,31 +1,39 @@
1
1
  import { Rljson } from './rljson.ts';
2
- /**
3
- * Provides Rljson examples
4
- */
5
2
  export declare class Example {
6
- /**
7
- * Returns the Rljson bakery example
8
- */
9
- static bakery(): Rljson;
10
- /**
11
- * Returns an Rljson object with one row containing all JSON types
12
- */
13
- static withAllJsonTypes(): Rljson;
14
- /**
15
- * Returns an empty Rljson object
16
- */
17
- static empty(): Rljson;
18
- /**
19
- * Returns an Rljson with a table containing all combinations of true and
20
- * false. This is useful for testing search operators.
21
- */
22
- static binary(): Rljson;
23
- /**
24
- * An more complex example containing an table with multiple rows
25
- */
26
- static multiRow(): Rljson;
27
- /**
28
- * Returns an Rljson object with a broken table name
29
- */
30
- static withBrokenTableName(): Rljson;
3
+ static readonly ok: {
4
+ bakery: () => Rljson;
5
+ empty: () => Rljson;
6
+ binary: () => Rljson;
7
+ singleRow: () => Rljson;
8
+ multipleRows: () => Rljson;
9
+ singleRef: () => Rljson;
10
+ complete: () => Rljson;
11
+ };
12
+ static readonly broken: {
13
+ brokenTableName: () => {
14
+ brok$en: {
15
+ _type: string;
16
+ _data: never[];
17
+ };
18
+ };
19
+ missingData: () => Rljson;
20
+ dataNotBeingAnArray: () => Rljson;
21
+ missingRef: () => Rljson;
22
+ missingReferencedTable: () => Rljson;
23
+ collections: {
24
+ missingBase: () => Rljson;
25
+ missingIdSet: () => Rljson;
26
+ missingAssignedPropertyTable: () => Rljson;
27
+ missingAssignedProperty: () => Rljson;
28
+ };
29
+ cakes: {
30
+ missingIdSet: () => Rljson;
31
+ missingCollectionsTable: () => Rljson;
32
+ missingLayerCollection: () => Rljson;
33
+ };
34
+ buffets: {
35
+ missingTable: () => Rljson;
36
+ missingItems: () => Rljson;
37
+ };
38
+ };
31
39
  }
package/dist/index.d.ts CHANGED
@@ -4,5 +4,6 @@ export * from './content/collection.ts';
4
4
  export * from './content/id-set.ts';
5
5
  export * from './content/properties.ts';
6
6
  export * from './example.ts';
7
+ export * from './rljson-indexed.ts';
7
8
  export * from './rljson.ts';
8
9
  export * from './typedefs.ts';
@@ -0,0 +1,19 @@
1
+ import { Json } from '@rljson/json';
2
+ import { Rljson } from './rljson.ts';
3
+ /**
4
+ * An Rljson object where all tables' rows are indexed by their hash.
5
+ */
6
+ export interface RljsonIndexed {
7
+ [tableName: string]: {
8
+ _data: {
9
+ [rowHash: string]: Json;
10
+ };
11
+ };
12
+ [key: `_${string}`]: any;
13
+ }
14
+ /**
15
+ * Returns an rljson where all tables' rows are indexed by their hash.
16
+ * @param rljson - The Rljson object to index
17
+ * @returns The indexed Rljson object
18
+ */
19
+ export declare const rljsonIndexed: (rljson: Rljson) => RljsonIndexed;
package/dist/rljson.d.ts CHANGED
@@ -4,7 +4,7 @@ import { CakesTable } from './content/cake.ts';
4
4
  import { CollectionsTable } from './content/collection.ts';
5
5
  import { IdSetsTable } from './content/id-set.ts';
6
6
  import { PropertiesTable } from './content/properties.ts';
7
- import { ContentType, TableName } from './typedefs.ts';
7
+ import { ContentType, Ref, TableName } from './typedefs.ts';
8
8
  export declare const reservedFieldNames: string[];
9
9
  export declare const reservedTableNames: string[];
10
10
  /**
@@ -12,8 +12,22 @@ export declare const reservedTableNames: string[];
12
12
  */
13
13
  export type TableType = BuffetsTable | PropertiesTable<any> | CollectionsTable | IdSetsTable | CakesTable;
14
14
  /** The rljson data format */
15
- export type Rljson = {
15
+ export interface Rljson extends Json {
16
16
  [tableId: TableName]: TableType;
17
+ }
18
+ /**
19
+ * Rljson set with private fields
20
+ */
21
+ export type RljsonPrivate = {
22
+ /**
23
+ * Contains id sets used accross the Rljson object
24
+ */
25
+ _idSets: IdSetsTable;
26
+ /**
27
+ * Used by validation. If external references are not present,
28
+ * validation does not throw an error.
29
+ */
30
+ _externalRefs: Ref[];
17
31
  };
18
32
  /** An example rljson object */
19
33
  export declare const exampleRljson: () => Rljson;
@@ -21,6 +35,13 @@ export declare const exampleRljson: () => Rljson;
21
35
  export interface RljsonTable<Data extends Json, Type extends ContentType> extends Json {
22
36
  /** The data rows of the table */
23
37
  _data: Data[];
24
- /** The type of the table */
38
+ /** The type of the table. If not set, the type is "properties" */
25
39
  _type: Type;
26
40
  }
41
+ /**
42
+ * Iterates over all tables of an Rljson object.
43
+ * Skips private members starting with _
44
+ * @param rljson - The Rljson object to iterate
45
+ * @param callback - The callback to call for each table
46
+ */
47
+ export declare const iterateTables: (rljson: Rljson, callback: (tableName: string, table: TableType) => void) => void;
package/dist/rljson.js CHANGED
@@ -1,160 +1,147 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { hip, hsh } from "@rljson/hash";
1
5
  import { exampleJsonObject } from "@rljson/json";
2
6
  // @license
3
- const bakeryExample = {
4
- buffets: {
5
- _type: "buffets",
6
- _data: [
7
- // Counter
8
- {
9
- items: [
10
- // Angle pie
11
- {
12
- table: "cakes",
13
- ref: "ap"
7
+ const bakeryExample = () => {
8
+ return {
9
+ // Every rljson object has a list of id-sets other objects can refer to
10
+ _idSets: {
11
+ _type: "idSets",
12
+ _data: [
13
+ {
14
+ add: ["slice0", "slice1"],
15
+ _hash: "KAwCRFD4mdx8b1bzxBb2_O"
16
+ }
17
+ ]
18
+ },
19
+ // A bakery offers a variety of buffets containing different pastries
20
+ buffets: {
21
+ _type: "buffets",
22
+ _data: [
23
+ {
24
+ items: [{ table: "cakes", ref: "fw8IrV05Z1ZekPXTdUdmt8" }]
25
+ }
26
+ ]
27
+ },
28
+ // A cake is a collection of layers, i.e. a base, a filling and a topping.
29
+ // Each layer of the cake has the same slice structure.
30
+ cakes: {
31
+ _type: "cakes",
32
+ _data: [
33
+ {
34
+ idSet: "KAwCRFD4mdx8b1bzxBb2_O",
35
+ collections: "layers",
36
+ layers: {
37
+ _hash: "50ZHxZ8KeUYJ3NC7ax5CbR"
14
38
  },
15
- // Cumb cake
16
- {
17
- table: "cakes",
18
- ref: "cc"
19
- }
20
- ]
21
- },
22
- // Fridge
23
- {
24
- id: "fridge",
25
- items: [
26
- // Black forest cake
27
- {
28
- table: "cakes",
29
- ref: "bfc"
39
+ _hash: "gMqFPTkYU66L32jDYZiZ79"
40
+ }
41
+ ],
42
+ _hash: "fw8IrV05Z1ZekPXTdUdmt8"
43
+ },
44
+ // Cakes are cut into slices. The cake layers are shared among the slices.
45
+ slices: {
46
+ _type: "idSets",
47
+ _data: [
48
+ {
49
+ add: ["slice0", "slice1"],
50
+ remove: []
51
+ }
52
+ ]
53
+ },
54
+ // A layer is a collection of ingredients described by a recipe
55
+ layers: {
56
+ _type: "collections",
57
+ _data: [
58
+ {
59
+ properties: "recipes",
60
+ assign: {
61
+ slice0: "VXUW79JrkOAG_pQ-75ahH5",
62
+ slice1: "VXUW79JrkOAG_pQ-75ahH5",
63
+ _hash: "Di4uG3-DHSq3_ArFu0V68m"
30
64
  },
31
- // Lemon cheese cake
32
- {
33
- table: "cakes",
34
- ref: "lcc"
35
- }
36
- ]
37
- }
38
- ]
39
- },
40
- cakes: {
41
- _type: "cakes",
42
- _data: []
43
- },
44
- layers: {
45
- _type: "collections",
46
- _data: []
47
- },
48
- sliceIds: {
49
- _type: "idSets",
50
- _data: [
51
- {
52
- base: null,
53
- add: [
54
- "slice0",
55
- "slice1",
56
- "slice2",
57
- "slice3",
58
- "slice4",
59
- "slice5",
60
- "slice6",
61
- "slice7",
62
- "slice8",
63
- "slice9",
64
- "slice10",
65
- "slice11"
66
- ],
67
- remove: []
68
- }
69
- ]
70
- },
71
- nutritiveValues: {
72
- _type: "properties",
73
- _data: []
74
- }
65
+ _hash: "IIg0e-6Qr73s7sNZe0RhKs"
66
+ }
67
+ ],
68
+ _hash: "e3utfEf_VS1-ljAMgqesua"
69
+ },
70
+ // Recipes are sets of ingredients
71
+ recipes: {
72
+ _type: "collections",
73
+ _data: [
74
+ {
75
+ properties: "recipeIngredients",
76
+ assign: {
77
+ flour: "mqLl7Q44V1t2MotJvaVRM_",
78
+ _hash: "UImWlyWZTSGhNAMC1JUzF1"
79
+ },
80
+ _hash: "G1YV_P8-_vTxtkXXHJeNBI"
81
+ }
82
+ ],
83
+ _hash: "r3lw7VsnywyasRmtynZqIt"
84
+ },
85
+ // A recipe ingredient combines an ingredient type with a quantity
86
+ recipeIngredients: {
87
+ _type: "properties",
88
+ _data: [
89
+ {
90
+ ingredientTypesRef: "WOfnFT1svec3iJ6x",
91
+ quantity: 500,
92
+ _hash: "mqLl7Q44V1t2MotJvaVRM_"
93
+ }
94
+ ],
95
+ _hash: "J7GJEjCRXLNfdAHARg_fzx"
96
+ },
97
+ // A table describing basic properties of ingredients
98
+ ingredients: {
99
+ _type: "properties",
100
+ _data: [
101
+ {
102
+ name: "flour",
103
+ amountUnit: "g",
104
+ nutritiveValuesRef: "gZXFSlrl5QAs5hOVsq5sWB",
105
+ _hash: "CdSJV-WOfnFT1svec3iJ6x"
106
+ }
107
+ ],
108
+ _hash: "FgJeTM0NcZvXwFcU-PD8Jf"
109
+ },
110
+ // A table with nutritive values of ingredients
111
+ nutritiveValues: {
112
+ _type: "properties",
113
+ _data: [
114
+ {
115
+ energy: 364,
116
+ fat: 0.98,
117
+ protein: 10.33,
118
+ carbohydrates: 76.31,
119
+ _hash: "gZXFSlrl5QAs5hOVsq5sWB"
120
+ }
121
+ ],
122
+ _hash: "7k4OqQtk71w3yVGMoA9F6p"
123
+ }
124
+ };
75
125
  };
76
126
  // @license
77
- const exampleBuffetsTable = bakeryExample.buffets;
127
+ const exampleBuffetsTable = () => bakeryExample().buffets;
78
128
  // @license
79
- const exampleCakesTable = Object.freeze(bakeryExample.cakes);
129
+ const exampleCakesTable = () => bakeryExample().cakes;
80
130
  // @license
81
- const exampleCollectionsTable = Object.freeze(
82
- bakeryExample.layers
83
- );
131
+ const exampleCollectionsTable = () => bakeryExample().layers;
84
132
  // @license
85
- const exampleIdSetsTable = Object.freeze(bakeryExample.sliceIds);
133
+ const exampleIdSetsTable = () => bakeryExample().slices;
86
134
  // @license
87
- const examplePropertiesTable = Object.freeze(bakeryExample.nutritiveValues);
135
+ const examplePropertiesTable = () => bakeryExample().nutritiveValues;
88
136
  // @license
89
- class Example {
90
- /**
91
- * Returns the Rljson bakery example
92
- */
93
- static bakery() {
94
- return {
95
- // A bakery is a collection of buffets
96
- bakery: {
97
- name: "Bakery",
98
- _type: "buffets",
99
- _data: [
100
- // Counter
101
- {
102
- id: "counter",
103
- items: [
104
- // Angle pie
105
- {
106
- table: "cakes",
107
- ref: "ap"
108
- },
109
- // Cumb cake
110
- {
111
- table: "cakes",
112
- ref: "cc"
113
- }
114
- ]
115
- },
116
- // Fridge
117
- {
118
- id: "fridge",
119
- items: [
120
- // Black forest
121
- {
122
- table: "cakes",
123
- ref: "bf"
124
- },
125
- // Lemon cheese cake
126
- {
127
- table: "cakes",
128
- ref: "cc"
129
- }
130
- ]
131
- }
132
- ]
133
- }
134
- };
135
- }
136
- /**
137
- * Returns an Rljson object with one row containing all JSON types
138
- */
139
- static withAllJsonTypes() {
140
- return {
141
- table: {
142
- _type: "properties",
143
- _data: [exampleJsonObject()]
144
- }
145
- };
146
- }
147
- /**
148
- * Returns an empty Rljson object
149
- */
150
- static empty() {
137
+ const _Example = class _Example {
138
+ };
139
+ __publicField(_Example, "ok", {
140
+ bakery: () => bakeryExample(),
141
+ empty: () => {
151
142
  return {};
152
- }
153
- /**
154
- * Returns an Rljson with a table containing all combinations of true and
155
- * false. This is useful for testing search operators.
156
- */
157
- static binary() {
143
+ },
144
+ binary: () => {
158
145
  return {
159
146
  table: {
160
147
  _type: "properties",
@@ -166,11 +153,16 @@ class Example {
166
153
  ]
167
154
  }
168
155
  };
169
- }
170
- /**
171
- * An more complex example containing an table with multiple rows
172
- */
173
- static multiRow() {
156
+ },
157
+ singleRow: () => {
158
+ return {
159
+ table: {
160
+ _type: "properties",
161
+ _data: [exampleJsonObject()]
162
+ }
163
+ };
164
+ },
165
+ multipleRows: () => {
174
166
  return {
175
167
  table: {
176
168
  _type: "properties",
@@ -199,30 +191,274 @@ class Example {
199
191
  ]
200
192
  }
201
193
  };
194
+ },
195
+ singleRef: () => {
196
+ return {
197
+ tableA: {
198
+ _type: "properties",
199
+ _data: [
200
+ {
201
+ keyA0: "a0"
202
+ },
203
+ {
204
+ keyA1: "a1"
205
+ }
206
+ ]
207
+ },
208
+ tableB: {
209
+ _type: "properties",
210
+ _data: [
211
+ {
212
+ tableARef: "KFQrf4mEz0UPmUaFHwH4T6"
213
+ }
214
+ ]
215
+ }
216
+ };
217
+ },
218
+ complete: () => {
219
+ return {
220
+ _idSets: {
221
+ _type: "idSets",
222
+ _data: [
223
+ {
224
+ add: ["id0", "id1"],
225
+ _hash: "MgHRBYSrhpyl4rvsOmAWcQ"
226
+ }
227
+ ]
228
+ },
229
+ properties: {
230
+ _type: "properties",
231
+ _data: [
232
+ { a: "0", _hash: "AFhW-fMzdCiz6bUZscp1Lf" },
233
+ { a: "1", _hash: "mv6w8rID8lQxLsje1EHQMY" }
234
+ ]
235
+ },
236
+ collections: {
237
+ _type: "collections",
238
+ _data: [
239
+ {
240
+ idSet: "MgHRBYSrhpyl4rvsOmAWcQ",
241
+ properties: "properties",
242
+ _hash: "sxv2NCM6UNOcX-i9FhOs5W",
243
+ assign: {}
244
+ },
245
+ {
246
+ base: "sxv2NCM6UNOcX-i9FhOs5W",
247
+ idSet: "MgHRBYSrhpyl4rvsOmAWcQ",
248
+ properties: "properties",
249
+ assign: {
250
+ id0: "AFhW-fMzdCiz6bUZscp1Lf",
251
+ id1: "mv6w8rID8lQxLsje1EHQMY"
252
+ },
253
+ _hash: "QB2JC6X_-rUAoixuldzWP-"
254
+ }
255
+ ]
256
+ },
257
+ cakes: {
258
+ _type: "cakes",
259
+ _data: [
260
+ {
261
+ idSet: "MgHRBYSrhpyl4rvsOmAWcQ",
262
+ collections: "collections",
263
+ layers: {
264
+ layer0: "sxv2NCM6UNOcX-i9FhOs5W",
265
+ layer1: "QB2JC6X_-rUAoixuldzWP-"
266
+ },
267
+ _hash: "QlTVJL3uoXO1L_fw2evLPe"
268
+ }
269
+ ]
270
+ },
271
+ buffets: {
272
+ _type: "buffets",
273
+ _data: [
274
+ {
275
+ items: [
276
+ {
277
+ table: "cakes",
278
+ ref: "QlTVJL3uoXO1L_fw2evLPe"
279
+ },
280
+ {
281
+ table: "collections",
282
+ ref: "QB2JC6X_-rUAoixuldzWP-"
283
+ }
284
+ ]
285
+ }
286
+ ]
287
+ }
288
+ };
202
289
  }
203
- /**
204
- * Returns an Rljson object with a broken table name
205
- */
206
- static withBrokenTableName() {
290
+ });
291
+ __publicField(_Example, "broken", {
292
+ brokenTableName: () => {
207
293
  return {
208
294
  brok$en: {
209
295
  _type: "properties",
210
296
  _data: []
211
297
  }
212
298
  };
299
+ },
300
+ missingData: () => {
301
+ return {
302
+ table: {
303
+ _type: "properties"
304
+ }
305
+ };
306
+ },
307
+ dataNotBeingAnArray: () => {
308
+ return {
309
+ table: {
310
+ _type: "properties",
311
+ _data: {}
312
+ }
313
+ };
314
+ },
315
+ missingRef: () => {
316
+ return {
317
+ tableA: {
318
+ _type: "properties",
319
+ _data: [
320
+ {
321
+ keyA0: "a0"
322
+ },
323
+ {
324
+ keyA1: "a1"
325
+ }
326
+ ]
327
+ },
328
+ tableB: {
329
+ _type: "properties",
330
+ _data: [
331
+ {
332
+ tableARef: "MISSINGREF"
333
+ // MISSINGREF does not exist in tableA
334
+ }
335
+ ]
336
+ }
337
+ };
338
+ },
339
+ missingReferencedTable: () => {
340
+ return {
341
+ tableB: {
342
+ _type: "properties",
343
+ _data: [
344
+ {
345
+ tableARef: "MISSINGREF"
346
+ // tableA is missing
347
+ }
348
+ ]
349
+ }
350
+ };
351
+ },
352
+ collections: {
353
+ missingBase: () => {
354
+ const result = _Example.ok.complete();
355
+ const collection1 = result.collections._data[1];
356
+ collection1.base = "MISSING";
357
+ return hip(result, true, false);
358
+ },
359
+ missingIdSet: () => {
360
+ const result = _Example.ok.complete();
361
+ const collection1 = result.collections._data[1];
362
+ collection1.idSet = "MISSING1";
363
+ return hip(result, true, false);
364
+ },
365
+ missingAssignedPropertyTable: () => {
366
+ const result = _Example.ok.complete();
367
+ delete result.properties;
368
+ return result;
369
+ },
370
+ missingAssignedProperty: () => {
371
+ const result = _Example.ok.complete();
372
+ result.properties._data.splice(1, 2);
373
+ return result;
374
+ }
375
+ },
376
+ cakes: {
377
+ missingIdSet: () => {
378
+ const result = _Example.ok.complete();
379
+ result.cakes._data[0].idSet = "MISSING";
380
+ hip(result.cakes, true, false);
381
+ return result;
382
+ },
383
+ missingCollectionsTable: () => {
384
+ const result = _Example.ok.complete();
385
+ result.cakes._data[0].collections = "MISSING";
386
+ hip(result.cakes, true, false);
387
+ return result;
388
+ },
389
+ missingLayerCollection: () => {
390
+ const result = _Example.ok.complete();
391
+ result.cakes._data[0].layers["layer0"] = "MISSING0";
392
+ result.cakes._data[0].layers["layer1"] = "MISSING1";
393
+ hip(result.cakes, true, false);
394
+ return result;
395
+ }
396
+ },
397
+ buffets: {
398
+ missingTable: () => {
399
+ const result = _Example.ok.complete();
400
+ const buffet = result.buffets._data[0];
401
+ buffet.items[0].table = "MISSING0";
402
+ buffet.items[1].table = "MISSING1";
403
+ hip(buffet, true, false);
404
+ return result;
405
+ },
406
+ missingItems: () => {
407
+ const result = _Example.ok.complete();
408
+ const buffet = result.buffets._data[0];
409
+ buffet.items[0].ref = "MISSING0";
410
+ buffet.items[1].ref = "MISSING1";
411
+ hip(buffet, true, false);
412
+ return result;
413
+ }
414
+ }
415
+ });
416
+ let Example = _Example;
417
+ // @license
418
+ const rljsonIndexed = (rljson) => {
419
+ const result = {};
420
+ for (const key in rljson) {
421
+ const item = rljson[key];
422
+ if (typeof item != "object") {
423
+ result[key] = item;
424
+ continue;
425
+ }
426
+ const dataIndexed = {};
427
+ result[key] = { ...item };
428
+ if (!Array.isArray(item._data)) {
429
+ continue;
430
+ }
431
+ for (const row of item._data) {
432
+ const hashedRow = row._hash ? row : hsh(row);
433
+ const hash = hashedRow._hash;
434
+ dataIndexed[hash] = hashedRow;
435
+ }
436
+ result[key]._data = dataIndexed;
213
437
  }
214
- }
438
+ return result;
439
+ };
215
440
  // @license
216
441
  const reservedFieldNames = ["_type", "_data"];
217
442
  const reservedTableNames = ["_hash", "_tables", "_columns"];
218
- const exampleRljson = () => Example.withAllJsonTypes();
443
+ const exampleRljson = () => Example.ok.singleRow();
444
+ const iterateTables = (rljson, callback) => {
445
+ for (const tableName in rljson) {
446
+ const value = rljson[tableName];
447
+ if (typeof value !== "object" || !Array.isArray(value._data)) {
448
+ continue;
449
+ }
450
+ callback(tableName, rljson[tableName]);
451
+ }
452
+ };
219
453
  // @license
220
- const exampleTypedefs = Object.freeze({
221
- ref: "ref",
222
- itemId: "itemId",
223
- tableName: "tableName",
224
- contentType: "collections"
225
- });
454
+ const exampleTypedefs = () => {
455
+ return {
456
+ ref: "ref",
457
+ itemId: "itemId",
458
+ tableName: "tableName",
459
+ contentType: "collections"
460
+ };
461
+ };
226
462
  export {
227
463
  Example,
228
464
  exampleBuffetsTable,
@@ -232,6 +468,8 @@ export {
232
468
  examplePropertiesTable,
233
469
  exampleRljson,
234
470
  exampleTypedefs,
471
+ iterateTables,
235
472
  reservedFieldNames,
236
- reservedTableNames
473
+ reservedTableNames,
474
+ rljsonIndexed
237
475
  };
@@ -4,147 +4,317 @@
4
4
  // Use of this source code is governed by terms that can be
5
5
  // found in the LICENSE file in the root of this package.
6
6
 
7
+ import { hip } from '@rljson/hash';
7
8
  import { exampleJsonObject } from '@rljson/json';
8
9
 
9
- import { BuffetsTable } from './content/buffet.ts';
10
+ import { bakeryExample } from './example/bakery-example.ts';
10
11
  import { Rljson } from './rljson.ts';
11
12
 
12
- /**
13
- * Provides Rljson examples
14
- */
15
13
  export class Example {
16
- /**
17
- * Returns the Rljson bakery example
18
- */
19
- static bakery(): Rljson {
20
- return {
21
- // A bakery is a collection of buffets
22
- bakery: {
23
- name: 'Bakery',
24
- _type: 'buffets',
25
- _data: [
26
- // Counter
27
- {
28
- id: 'counter',
29
- items: [
30
- // Angle pie
31
- {
32
- table: 'cakes',
33
- ref: 'ap',
34
- },
14
+ static readonly ok = {
15
+ bakery: (): Rljson => bakeryExample(),
35
16
 
36
- // Cumb cake
37
- {
38
- table: 'cakes',
39
- ref: 'cc',
40
- },
41
- ],
42
- },
43
-
44
- // Fridge
45
- {
46
- id: 'fridge',
47
- items: [
48
- // Black forest
49
- {
50
- table: 'cakes',
51
- ref: 'bf',
17
+ empty: (): Rljson => {
18
+ return {};
19
+ },
20
+
21
+ binary: (): Rljson => {
22
+ return {
23
+ table: {
24
+ _type: 'properties',
25
+ _data: [
26
+ { a: false, b: false },
27
+ { a: false, b: true },
28
+ { a: true, b: false },
29
+ { a: true, b: true },
30
+ ],
31
+ },
32
+ };
33
+ },
34
+
35
+ singleRow: (): Rljson => {
36
+ return {
37
+ table: {
38
+ _type: 'properties',
39
+ _data: [exampleJsonObject()],
40
+ },
41
+ };
42
+ },
43
+
44
+ multipleRows: (): Rljson => {
45
+ return {
46
+ table: {
47
+ _type: 'properties',
48
+ _data: [
49
+ {
50
+ string: 'str0',
51
+ boolean: true,
52
+ number: 1,
53
+ array: [1, 'str0', true, { a: { b: 'c' } }],
54
+ object: { a: { b: 'c' } },
55
+ },
56
+
57
+ {
58
+ string: 'str1',
59
+ boolean: true,
60
+ number: 1,
61
+ array: [1, 'str1', true, { a: { b: 'c' } }],
62
+ object: { a: { b: 'c' } },
63
+ },
64
+
65
+ {
66
+ string: 'str2',
67
+ boolean: false,
68
+ number: 1,
69
+ array: [1, 'str1', true, { a: { b: 'c' } }],
70
+ object: { d: { e: 'f' } },
71
+ },
72
+ ],
73
+ },
74
+ };
75
+ },
76
+
77
+ singleRef: (): Rljson => {
78
+ return {
79
+ tableA: {
80
+ _type: 'properties',
81
+ _data: [
82
+ {
83
+ keyA0: 'a0',
84
+ },
85
+ {
86
+ keyA1: 'a1',
87
+ },
88
+ ],
89
+ },
90
+ tableB: {
91
+ _type: 'properties',
92
+ _data: [
93
+ {
94
+ tableARef: 'KFQrf4mEz0UPmUaFHwH4T6',
95
+ },
96
+ ],
97
+ },
98
+ };
99
+ },
100
+ complete: (): Rljson => {
101
+ return {
102
+ _idSets: {
103
+ _type: 'idSets',
104
+
105
+ _data: [
106
+ {
107
+ add: ['id0', 'id1'],
108
+ _hash: 'MgHRBYSrhpyl4rvsOmAWcQ',
109
+ },
110
+ ],
111
+ },
112
+
113
+ properties: {
114
+ _type: 'properties',
115
+ _data: [
116
+ { a: '0', _hash: 'AFhW-fMzdCiz6bUZscp1Lf' },
117
+ { a: '1', _hash: 'mv6w8rID8lQxLsje1EHQMY' },
118
+ ],
119
+ },
120
+
121
+ collections: {
122
+ _type: 'collections',
123
+ _data: [
124
+ {
125
+ idSet: 'MgHRBYSrhpyl4rvsOmAWcQ',
126
+ properties: 'properties',
127
+ _hash: 'sxv2NCM6UNOcX-i9FhOs5W',
128
+ assign: {},
129
+ },
130
+ {
131
+ base: 'sxv2NCM6UNOcX-i9FhOs5W',
132
+ idSet: 'MgHRBYSrhpyl4rvsOmAWcQ',
133
+ properties: 'properties',
134
+ assign: {
135
+ id0: 'AFhW-fMzdCiz6bUZscp1Lf',
136
+ id1: 'mv6w8rID8lQxLsje1EHQMY',
52
137
  },
138
+ _hash: 'QB2JC6X_-rUAoixuldzWP-',
139
+ },
140
+ ],
141
+ },
53
142
 
54
- // Lemon cheese cake
55
- {
56
- table: 'cakes',
57
- ref: 'cc',
143
+ cakes: {
144
+ _type: 'cakes',
145
+ _data: [
146
+ {
147
+ idSet: 'MgHRBYSrhpyl4rvsOmAWcQ',
148
+ collections: 'collections',
149
+ layers: {
150
+ layer0: 'sxv2NCM6UNOcX-i9FhOs5W',
151
+ layer1: 'QB2JC6X_-rUAoixuldzWP-',
58
152
  },
59
- ],
60
- },
61
- ],
62
- } as BuffetsTable,
63
- };
64
- }
65
-
66
- /**
67
- * Returns an Rljson object with one row containing all JSON types
68
- */
69
- static withAllJsonTypes(): Rljson {
70
- return {
71
- table: {
72
- _type: 'properties',
73
- _data: [exampleJsonObject()],
153
+ _hash: 'QlTVJL3uoXO1L_fw2evLPe',
154
+ },
155
+ ],
156
+ },
157
+
158
+ buffets: {
159
+ _type: 'buffets',
160
+ _data: [
161
+ {
162
+ items: [
163
+ {
164
+ table: 'cakes',
165
+ ref: 'QlTVJL3uoXO1L_fw2evLPe',
166
+ },
167
+ {
168
+ table: 'collections',
169
+ ref: 'QB2JC6X_-rUAoixuldzWP-',
170
+ },
171
+ ],
172
+ },
173
+ ],
174
+ },
175
+ };
176
+ },
177
+ };
178
+
179
+ static readonly broken = {
180
+ brokenTableName: () => {
181
+ return {
182
+ brok$en: {
183
+ _type: 'properties',
184
+ _data: [],
185
+ },
186
+ };
187
+ },
188
+
189
+ missingData: () => {
190
+ return {
191
+ table: {
192
+ _type: 'properties',
193
+ },
194
+ } as unknown as Rljson;
195
+ },
196
+
197
+ dataNotBeingAnArray: () => {
198
+ return {
199
+ table: {
200
+ _type: 'properties',
201
+ _data: {},
202
+ },
203
+ } as unknown as Rljson;
204
+ },
205
+
206
+ missingRef: (): Rljson => {
207
+ return {
208
+ tableA: {
209
+ _type: 'properties',
210
+ _data: [
211
+ {
212
+ keyA0: 'a0',
213
+ },
214
+ {
215
+ keyA1: 'a1',
216
+ },
217
+ ],
218
+ },
219
+ tableB: {
220
+ _type: 'properties',
221
+ _data: [
222
+ {
223
+ tableARef: 'MISSINGREF', // MISSINGREF does not exist in tableA
224
+ },
225
+ ],
226
+ },
227
+ };
228
+ },
229
+
230
+ missingReferencedTable: (): Rljson => {
231
+ return {
232
+ tableB: {
233
+ _type: 'properties',
234
+ _data: [
235
+ {
236
+ tableARef: 'MISSINGREF', // tableA is missing
237
+ },
238
+ ],
239
+ },
240
+ };
241
+ },
242
+
243
+ collections: {
244
+ missingBase: (): Rljson => {
245
+ const result = Example.ok.complete();
246
+ const collection1 = result.collections._data[1];
247
+ collection1.base = 'MISSING'; // Missing base
248
+
249
+ // Recalculate hashes
250
+ return hip(result, true, false);
74
251
  },
75
- };
76
- }
77
-
78
- /**
79
- * Returns an empty Rljson object
80
- */
81
- static empty(): Rljson {
82
- return {};
83
- }
84
-
85
- /**
86
- * Returns an Rljson with a table containing all combinations of true and
87
- * false. This is useful for testing search operators.
88
- */
89
- static binary(): Rljson {
90
- return {
91
- table: {
92
- _type: 'properties',
93
- _data: [
94
- { a: false, b: false },
95
- { a: false, b: true },
96
- { a: true, b: false },
97
- { a: true, b: true },
98
- ],
252
+
253
+ missingIdSet: (): Rljson => {
254
+ const result = Example.ok.complete();
255
+ const collection1 = result.collections._data[1];
256
+
257
+ collection1.idSet = 'MISSING1';
258
+
259
+ // Recalculate hashes
260
+ return hip(result, true, false);
99
261
  },
100
- };
101
- }
102
-
103
- /**
104
- * An more complex example containing an table with multiple rows
105
- */
106
- static multiRow(): Rljson {
107
- return {
108
- table: {
109
- _type: 'properties',
110
- _data: [
111
- {
112
- string: 'str0',
113
- boolean: true,
114
- number: 1,
115
- array: [1, 'str0', true, { a: { b: 'c' } }],
116
- object: { a: { b: 'c' } },
117
- },
118
-
119
- {
120
- string: 'str1',
121
- boolean: true,
122
- number: 1,
123
- array: [1, 'str1', true, { a: { b: 'c' } }],
124
- object: { a: { b: 'c' } },
125
- },
126
-
127
- {
128
- string: 'str2',
129
- boolean: false,
130
- number: 1,
131
- array: [1, 'str1', true, { a: { b: 'c' } }],
132
- object: { d: { e: 'f' } },
133
- },
134
- ],
262
+
263
+ missingAssignedPropertyTable: (): Rljson => {
264
+ const result = Example.ok.complete();
265
+ delete result.properties; // Remove properties table
266
+ return result;
267
+ },
268
+
269
+ missingAssignedProperty: (): Rljson => {
270
+ const result = Example.ok.complete();
271
+ result.properties._data.splice(1, 2); // Remove an property that is assigne
272
+ return result;
135
273
  },
136
- };
137
- }
138
-
139
- /**
140
- * Returns an Rljson object with a broken table name
141
- */
142
- static withBrokenTableName(): Rljson {
143
- return {
144
- brok$en: {
145
- _type: 'properties',
146
- _data: [],
274
+ },
275
+
276
+ cakes: {
277
+ missingIdSet: (): Rljson => {
278
+ const result = Example.ok.complete();
279
+ result.cakes._data[0].idSet = 'MISSING'; // Missing ID set
280
+ hip(result.cakes, true, false);
281
+ return result;
282
+ },
283
+
284
+ missingCollectionsTable: (): Rljson => {
285
+ const result = Example.ok.complete();
286
+ result.cakes._data[0].collections = 'MISSING'; // Missing collections table
287
+ hip(result.cakes, true, false);
288
+ return result;
289
+ },
290
+
291
+ missingLayerCollection: (): Rljson => {
292
+ const result = Example.ok.complete();
293
+ result.cakes._data[0].layers['layer0'] = 'MISSING0';
294
+ result.cakes._data[0].layers['layer1'] = 'MISSING1';
295
+ hip(result.cakes, true, false);
296
+ return result;
297
+ },
298
+ },
299
+
300
+ buffets: {
301
+ missingTable: (): Rljson => {
302
+ const result = Example.ok.complete();
303
+ const buffet = result.buffets._data[0];
304
+ buffet.items[0].table = 'MISSING0';
305
+ buffet.items[1].table = 'MISSING1';
306
+ hip(buffet, true, false);
307
+ return result;
308
+ },
309
+
310
+ missingItems: (): Rljson => {
311
+ const result = Example.ok.complete();
312
+ const buffet = result.buffets._data[0];
313
+ buffet.items[0].ref = 'MISSING0';
314
+ buffet.items[1].ref = 'MISSING1';
315
+ hip(buffet, true, false);
316
+ return result;
147
317
  },
148
- };
149
- }
318
+ },
319
+ };
150
320
  }
@@ -22,7 +22,10 @@ export type TableName = ItemId;
22
22
  * - `properties` Tables containing item properties
23
23
  */
24
24
  export type ContentType = 'buffets' | 'cakes' | 'collections' | 'idSets' | 'properties';
25
- export declare const exampleTypedefs: {
25
+ /**
26
+ * An example object using the typedefs
27
+ */
28
+ export declare const exampleTypedefs: () => {
26
29
  ref: Ref;
27
30
  itemId: ItemId;
28
31
  tableName: TableName;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rljson/rljson",
3
- "version": "0.0.12",
4
- "packageManager": "pnpm@10.6.2",
3
+ "version": "0.0.14",
4
+ "packageManager": "pnpm@10.6.3",
5
5
  "description": "The RLJSON data format specification",
6
6
  "homepage": "https://github.com/rljson/rljson",
7
7
  "bugs": "https://github.com/rljson/rljson/issues",
@@ -32,10 +32,10 @@
32
32
  "@types/node": "^22.13.10",
33
33
  "@typescript-eslint/eslint-plugin": "^8.26.1",
34
34
  "@typescript-eslint/parser": "^8.26.1",
35
- "@vitest/coverage-v8": "^3.0.8",
35
+ "@vitest/coverage-v8": "^3.0.9",
36
36
  "cross-env": "^7.0.3",
37
37
  "eslint": "^9.22.0",
38
- "eslint-plugin-jsdoc": "^50.6.6",
38
+ "eslint-plugin-jsdoc": "^50.6.8",
39
39
  "eslint-plugin-tsdoc": "^0.4.0",
40
40
  "globals": "^16.0.0",
41
41
  "jsdoc": "^4.0.4",
@@ -43,15 +43,15 @@
43
43
  "typescript": "~5.8.2",
44
44
  "typescript-eslint": "^8.26.1",
45
45
  "vite": "^6.2.2",
46
- "vite-node": "^3.0.8",
46
+ "vite-node": "^3.0.9",
47
47
  "vite-plugin-dts": "^4.5.3",
48
48
  "vite-tsconfig-paths": "^5.1.4",
49
- "vitest": "^3.0.8",
49
+ "vitest": "^3.0.9",
50
50
  "vitest-dom": "^0.1.1"
51
51
  },
52
52
  "dependencies": {
53
- "@rljson/hash": "^0.0.11",
54
- "@rljson/json": "^0.0.13"
53
+ "@rljson/hash": "^0.0.12",
54
+ "@rljson/json": "^0.0.15"
55
55
  },
56
56
  "pnpm": {
57
57
  "onlyBuiltDependencies": [