@rljson/rljson 0.0.71 → 0.0.73
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/content/cake.d.ts +10 -1
- package/dist/content/head.d.ts +10 -0
- package/dist/content/slice-ids.d.ts +7 -0
- package/dist/content/table-cfg.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/rljson.d.ts +2 -1
- package/dist/rljson.js +106 -10
- package/dist/route/route.d.ts +5 -1
- package/dist/tools/time-id.d.ts +5 -5
- package/dist/typedefs.d.ts +1 -1
- package/package.json +9 -9
package/dist/content/cake.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Json } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
|
-
import { TableKey } from '../typedefs.ts';
|
|
3
|
+
import { Ref, SliceId, TableKey } from '../typedefs.ts';
|
|
4
4
|
import { LayerRef } from './layer.ts';
|
|
5
5
|
import { SliceIdsRef } from './slice-ids.ts';
|
|
6
6
|
import { TableCfg } from './table-cfg.ts';
|
|
@@ -8,6 +8,15 @@ import { TableCfg } from './table-cfg.ts';
|
|
|
8
8
|
* A `CakeLayerId` assigns an id or name to a cake layer
|
|
9
9
|
*/
|
|
10
10
|
export type CakeLayerId = string;
|
|
11
|
+
/**
|
|
12
|
+
* A reference to a cake
|
|
13
|
+
*
|
|
14
|
+
* A cake reference can optionally restrict the slice ids that are used in the cake.
|
|
15
|
+
*/
|
|
16
|
+
export interface CakeReference extends Json {
|
|
17
|
+
ref: Ref;
|
|
18
|
+
sliceIds?: SliceId[];
|
|
19
|
+
}
|
|
11
20
|
/**
|
|
12
21
|
* A cake is a collection of layers.
|
|
13
22
|
*
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Json } from '@rljson/json';
|
|
2
|
+
import { RljsonTable } from '../rljson.ts';
|
|
3
|
+
import { TableCfg } from './table-cfg.ts';
|
|
4
|
+
export interface Head extends Json {
|
|
5
|
+
timeId: string;
|
|
6
|
+
cakeRef: string;
|
|
7
|
+
_hash: string;
|
|
8
|
+
}
|
|
9
|
+
export type HeadsTable = RljsonTable<Head, 'head'>;
|
|
10
|
+
export declare const createHeadsTableCfg: (cakeKey: string) => TableCfg;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Json } from '@rljson/json';
|
|
2
2
|
import { RljsonTable } from '../rljson.ts';
|
|
3
3
|
import { Ref, SliceId } from '../typedefs.ts';
|
|
4
|
+
import { TableCfg } from './table-cfg.ts';
|
|
4
5
|
/**
|
|
5
6
|
* An SliceIdsRef is a hash pointing to an Ids
|
|
6
7
|
*/
|
|
@@ -30,3 +31,9 @@ export type SliceIdsTable = RljsonTable<SliceIds, 'sliceIds'>;
|
|
|
30
31
|
* Returns one of the layers of the example cake
|
|
31
32
|
*/
|
|
32
33
|
export declare const exampleSliceIdsTable: () => SliceIdsTable;
|
|
34
|
+
/**
|
|
35
|
+
* Creates a table configuration for slice ids table
|
|
36
|
+
* @param tableKey - the table key
|
|
37
|
+
* @returns the table configuration
|
|
38
|
+
*/
|
|
39
|
+
export declare const createSliceIdsTableCfg: (tableKey: string) => TableCfg;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './content/buffet.ts';
|
|
2
2
|
export * from './content/cake.ts';
|
|
3
3
|
export * from './content/components.ts';
|
|
4
|
+
export * from './content/head.ts';
|
|
4
5
|
export * from './content/layer.ts';
|
|
5
6
|
export * from './content/revision.ts';
|
|
6
7
|
export * from './content/slice-ids.ts';
|
package/dist/rljson.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Json } from '@rljson/json';
|
|
|
2
2
|
import { BuffetsTable } from './content/buffet.ts';
|
|
3
3
|
import { CakesTable } from './content/cake.ts';
|
|
4
4
|
import { ComponentsTable } from './content/components.ts';
|
|
5
|
+
import { HeadsTable } from './content/head.ts';
|
|
5
6
|
import { LayersTable } from './content/layer.ts';
|
|
6
7
|
import { RevisionsTable } from './content/revision.ts';
|
|
7
8
|
import { SliceIdsTable } from './content/slice-ids.ts';
|
|
@@ -16,7 +17,7 @@ export declare const reservedTableKeys: string[];
|
|
|
16
17
|
/**
|
|
17
18
|
* One of the supported Rljson table types
|
|
18
19
|
*/
|
|
19
|
-
export type TableType = BuffetsTable | ComponentsTable<any> | LayersTable | SliceIdsTable | CakesTable | RevisionsTable | TablesCfgTable | InsertHistoryTable<any> | EditsTable | MultiEditsTable | EditHistoryTable;
|
|
20
|
+
export type TableType = BuffetsTable | ComponentsTable<any> | LayersTable | SliceIdsTable | CakesTable | RevisionsTable | TablesCfgTable | InsertHistoryTable<any> | EditsTable | MultiEditsTable | EditHistoryTable | HeadsTable;
|
|
20
21
|
/** The rljson data format */
|
|
21
22
|
export interface Rljson extends Json {
|
|
22
23
|
[tableId: TableKey]: TableType;
|
package/dist/rljson.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { hip, hsh } from "@rljson/hash";
|
|
2
2
|
import { exampleJsonObject, jsonValueTypes, jsonValueMatchesType, jsonValueType } from "@rljson/json";
|
|
3
3
|
import { nanoid } from "nanoid";
|
|
4
|
+
const routeRefSeperator = "@";
|
|
5
|
+
const routeSliceIdIndicators = ["(", ")"];
|
|
6
|
+
const routeSliceIdSeperator = ",";
|
|
4
7
|
class Route {
|
|
5
8
|
constructor(_segments) {
|
|
6
9
|
this._segments = _segments;
|
|
@@ -16,12 +19,20 @@ class Route {
|
|
|
16
19
|
const segmentsFlat = route.split("/").filter((s) => s.length > 0);
|
|
17
20
|
const segments = [];
|
|
18
21
|
for (const segmentFlat of segmentsFlat) {
|
|
19
|
-
const [
|
|
22
|
+
const [tableKeyAndSliceId, refFlat] = segmentFlat.split(routeRefSeperator);
|
|
23
|
+
const sliceIds = tableKeyAndSliceId.substring(
|
|
24
|
+
tableKeyAndSliceId.indexOf(routeSliceIdIndicators[0]) + 1,
|
|
25
|
+
tableKeyAndSliceId.indexOf(routeSliceIdIndicators[1])
|
|
26
|
+
).split(routeSliceIdSeperator).filter((s) => s.length > 0);
|
|
27
|
+
const tableKey = tableKeyAndSliceId.split(routeSliceIdIndicators[0])[0];
|
|
20
28
|
const ref = !!refFlat ? refFlat.split(":").length == 2 ? { [tableKey + "InsertHistoryRef"]: refFlat } : { [tableKey + "Ref"]: refFlat } : {};
|
|
21
29
|
const segment = {
|
|
22
30
|
tableKey,
|
|
23
31
|
...ref
|
|
24
32
|
};
|
|
33
|
+
if (sliceIds.length > 0) {
|
|
34
|
+
segment.sliceIds = sliceIds;
|
|
35
|
+
}
|
|
25
36
|
segments.push(segment);
|
|
26
37
|
}
|
|
27
38
|
return new Route(segments);
|
|
@@ -46,8 +57,9 @@ class Route {
|
|
|
46
57
|
* @returns A new Route that is one level deeper or 'steps' levels deeper
|
|
47
58
|
*/
|
|
48
59
|
deeper(steps) {
|
|
60
|
+
let deeperRoute;
|
|
49
61
|
if (steps === void 0) {
|
|
50
|
-
|
|
62
|
+
deeperRoute = new Route(this._segments.slice(1, this._segments.length));
|
|
51
63
|
} else {
|
|
52
64
|
if (steps < 1) {
|
|
53
65
|
throw new Error("Steps must be greater than 0");
|
|
@@ -55,8 +67,14 @@ class Route {
|
|
|
55
67
|
if (steps >= this._segments.length) {
|
|
56
68
|
throw new Error("Cannot go deeper than the root");
|
|
57
69
|
}
|
|
58
|
-
|
|
70
|
+
deeperRoute = new Route(
|
|
71
|
+
this._segments.slice(steps, this._segments.length)
|
|
72
|
+
);
|
|
59
73
|
}
|
|
74
|
+
if (!!this.propertyKey) {
|
|
75
|
+
deeperRoute.propertyKey = this.propertyKey;
|
|
76
|
+
}
|
|
77
|
+
return deeperRoute;
|
|
60
78
|
}
|
|
61
79
|
// .............................................................................
|
|
62
80
|
/**
|
|
@@ -159,8 +177,13 @@ class Route {
|
|
|
159
177
|
let flat = "";
|
|
160
178
|
for (const segment of this._segments) {
|
|
161
179
|
const tableKey = segment.tableKey;
|
|
162
|
-
const
|
|
163
|
-
|
|
180
|
+
const tableKeyAndSliceId = segment.sliceIds ? `${tableKey}${routeSliceIdIndicators[0]}${segment.sliceIds.join(
|
|
181
|
+
routeSliceIdSeperator
|
|
182
|
+
)}${routeSliceIdIndicators[1]}` : tableKey;
|
|
183
|
+
const ref = Object.keys(segment).filter(
|
|
184
|
+
(k) => ["tableKey", "sliceIds"].indexOf(k) === -1
|
|
185
|
+
)[0];
|
|
186
|
+
flat += `/${tableKeyAndSliceId}${ref ? `${routeRefSeperator}${segment[ref]}` : ""}`;
|
|
164
187
|
}
|
|
165
188
|
return flat;
|
|
166
189
|
}
|
|
@@ -504,6 +527,36 @@ const createCakeTableCfg = (cakeKey) => ({
|
|
|
504
527
|
});
|
|
505
528
|
const exampleCakesTable = () => bakeryExample().cakes;
|
|
506
529
|
const exampleComponentsTable = () => bakeryExample().nutritionalValues;
|
|
530
|
+
const createHeadsTableCfg = (cakeKey) => ({
|
|
531
|
+
key: `${cakeKey}Heads`,
|
|
532
|
+
type: "head",
|
|
533
|
+
columns: [
|
|
534
|
+
{
|
|
535
|
+
key: "_hash",
|
|
536
|
+
type: "string",
|
|
537
|
+
titleLong: "Hash",
|
|
538
|
+
titleShort: "Hash"
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
key: "timeId",
|
|
542
|
+
type: "string",
|
|
543
|
+
titleLong: "Time Identifier",
|
|
544
|
+
titleShort: "Time ID"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
key: "cakeRef",
|
|
548
|
+
type: "string",
|
|
549
|
+
titleLong: "Cake Reference",
|
|
550
|
+
titleShort: "Cake Ref",
|
|
551
|
+
ref: {
|
|
552
|
+
tableKey: `${cakeKey}`
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
],
|
|
556
|
+
isHead: false,
|
|
557
|
+
isRoot: false,
|
|
558
|
+
isShared: true
|
|
559
|
+
});
|
|
507
560
|
const createLayerTableCfg = (layerKey) => ({
|
|
508
561
|
key: layerKey,
|
|
509
562
|
type: "layers",
|
|
@@ -544,6 +597,34 @@ const exampleRevision = () => ({
|
|
|
544
597
|
timestamp: 1743558427
|
|
545
598
|
});
|
|
546
599
|
const exampleSliceIdsTable = () => bakeryExample().slices;
|
|
600
|
+
const createSliceIdsTableCfg = (tableKey) => ({
|
|
601
|
+
key: tableKey,
|
|
602
|
+
type: "sliceIds",
|
|
603
|
+
columns: [
|
|
604
|
+
{ key: "_hash", type: "string", titleLong: "Hash", titleShort: "Hash" },
|
|
605
|
+
{
|
|
606
|
+
key: "base",
|
|
607
|
+
type: "string",
|
|
608
|
+
titleLong: "Base SliceId",
|
|
609
|
+
titleShort: "Base SliceId"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
key: "add",
|
|
613
|
+
type: "jsonArray",
|
|
614
|
+
titleLong: "Added SliceIds",
|
|
615
|
+
titleShort: "Add"
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
key: "remove",
|
|
619
|
+
type: "jsonArray",
|
|
620
|
+
titleLong: "Removed SliceIds",
|
|
621
|
+
titleShort: "Remove"
|
|
622
|
+
}
|
|
623
|
+
],
|
|
624
|
+
isHead: false,
|
|
625
|
+
isRoot: false,
|
|
626
|
+
isShared: true
|
|
627
|
+
});
|
|
547
628
|
class Example {
|
|
548
629
|
static ok = {
|
|
549
630
|
bakery: () => bakeryExample(),
|
|
@@ -1458,7 +1539,7 @@ const createEditHistoryTableCfg = (cakeKey) => ({
|
|
|
1458
1539
|
titleLong: "Multi Edit Reference",
|
|
1459
1540
|
titleShort: "Multi Edit Ref",
|
|
1460
1541
|
ref: {
|
|
1461
|
-
tableKey: `${cakeKey}
|
|
1542
|
+
tableKey: `${cakeKey}MultiEdits`
|
|
1462
1543
|
}
|
|
1463
1544
|
},
|
|
1464
1545
|
{
|
|
@@ -1476,7 +1557,10 @@ const createEditHistoryTableCfg = (cakeKey) => ({
|
|
|
1476
1557
|
titleLong: "Previous Values",
|
|
1477
1558
|
titleShort: "Previous"
|
|
1478
1559
|
}
|
|
1479
|
-
]
|
|
1560
|
+
],
|
|
1561
|
+
isHead: false,
|
|
1562
|
+
isRoot: false,
|
|
1563
|
+
isShared: true
|
|
1480
1564
|
});
|
|
1481
1565
|
const createEditTableCfg = (cakeKey) => ({
|
|
1482
1566
|
key: `${cakeKey}Edits`,
|
|
@@ -1500,7 +1584,10 @@ const createEditTableCfg = (cakeKey) => ({
|
|
|
1500
1584
|
titleLong: "Edit Action Data",
|
|
1501
1585
|
titleShort: "Action"
|
|
1502
1586
|
}
|
|
1503
|
-
]
|
|
1587
|
+
],
|
|
1588
|
+
isHead: false,
|
|
1589
|
+
isRoot: false,
|
|
1590
|
+
isShared: true
|
|
1504
1591
|
});
|
|
1505
1592
|
const createMultiEditTableCfg = (cakeKey) => ({
|
|
1506
1593
|
key: `${cakeKey}MultiEdits`,
|
|
@@ -1527,7 +1614,10 @@ const createMultiEditTableCfg = (cakeKey) => ({
|
|
|
1527
1614
|
tableKey: `${cakeKey}Edits`
|
|
1528
1615
|
}
|
|
1529
1616
|
}
|
|
1530
|
-
]
|
|
1617
|
+
],
|
|
1618
|
+
isHead: false,
|
|
1619
|
+
isRoot: false,
|
|
1620
|
+
isShared: true
|
|
1531
1621
|
});
|
|
1532
1622
|
const objectDepth = (o) => Object(o) === o ? 1 + Math.max(-1, ...Object.values(o).map(objectDepth)) : 0;
|
|
1533
1623
|
class InsertValidator {
|
|
@@ -1758,7 +1848,8 @@ const contentTypes = [
|
|
|
1758
1848
|
"insertHistory",
|
|
1759
1849
|
"edits",
|
|
1760
1850
|
"multiEdits",
|
|
1761
|
-
"editHistory"
|
|
1851
|
+
"editHistory",
|
|
1852
|
+
"head"
|
|
1762
1853
|
];
|
|
1763
1854
|
const exampleTypedefs = () => {
|
|
1764
1855
|
return {
|
|
@@ -2612,9 +2703,11 @@ export {
|
|
|
2612
2703
|
createCakeTableCfg,
|
|
2613
2704
|
createEditHistoryTableCfg,
|
|
2614
2705
|
createEditTableCfg,
|
|
2706
|
+
createHeadsTableCfg,
|
|
2615
2707
|
createInsertHistoryTableCfg,
|
|
2616
2708
|
createLayerTableCfg,
|
|
2617
2709
|
createMultiEditTableCfg,
|
|
2710
|
+
createSliceIdsTableCfg,
|
|
2618
2711
|
exampleBuffetsTable,
|
|
2619
2712
|
exampleCakesTable,
|
|
2620
2713
|
exampleComponentsTable,
|
|
@@ -2636,6 +2729,9 @@ export {
|
|
|
2636
2729
|
removeDuplicates,
|
|
2637
2730
|
reservedFieldNames,
|
|
2638
2731
|
reservedTableKeys,
|
|
2732
|
+
routeRefSeperator,
|
|
2733
|
+
routeSliceIdIndicators,
|
|
2734
|
+
routeSliceIdSeperator,
|
|
2639
2735
|
throwOnInvalidTableCfg,
|
|
2640
2736
|
timeId,
|
|
2641
2737
|
validateInsert,
|
package/dist/route/route.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { TableKey } from '../typedefs.ts';
|
|
1
|
+
import { SliceId, TableKey } from '../typedefs.ts';
|
|
2
2
|
export type RouteRef = string;
|
|
3
3
|
export type RouteSegment<Str extends string> = {
|
|
4
4
|
[key in Str as `${Uncapitalize<string & key>}Ref`]: string;
|
|
5
5
|
} & {
|
|
6
6
|
tableKey: TableKey;
|
|
7
|
+
sliceIds?: SliceId[];
|
|
7
8
|
};
|
|
9
|
+
export declare const routeRefSeperator = "@";
|
|
10
|
+
export declare const routeSliceIdIndicators: readonly ["(", ")"];
|
|
11
|
+
export declare const routeSliceIdSeperator: ",";
|
|
8
12
|
export type RouteSegmentFlat<N extends string> = `${N}` | `${N}@${string}` | `${N}@${string}:${string}`;
|
|
9
13
|
/**
|
|
10
14
|
* A class to handle routes in an Rljson object.
|
package/dist/tools/time-id.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generates a new TimeId.
|
|
3
|
-
* A TimeId
|
|
4
|
-
* - "xxxx" is a 4-character unique identifier
|
|
3
|
+
* A TimeId has the format "timestamp:xxxx" where:
|
|
5
4
|
* - "timestamp" is the current time in milliseconds since epoch
|
|
5
|
+
* - "xxxx" is a 4-character unique identifier
|
|
6
6
|
* @returns A new TimeId string
|
|
7
7
|
*/
|
|
8
8
|
export declare const timeId: () => string;
|
|
9
9
|
/**
|
|
10
10
|
* Checks if a given id is a valid TimeId.
|
|
11
|
-
* A
|
|
12
|
-
* - "
|
|
13
|
-
* - "
|
|
11
|
+
* A TimeId has the format "timestamp:xxxx" where:
|
|
12
|
+
* - "timestamp" is the current time in milliseconds since epoch
|
|
13
|
+
* - "xxxx" is a 4-character unique identifier
|
|
14
14
|
* @param id - The id to check
|
|
15
15
|
* @returns True if the id is a valid TimeId, false otherwise
|
|
16
16
|
*/
|
package/dist/typedefs.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type ColumnKey = JsonKey;
|
|
|
26
26
|
* - `ids` Tables containing slice ids
|
|
27
27
|
* - `components` Tables containing slice components
|
|
28
28
|
*/
|
|
29
|
-
export declare const contentTypes: readonly ["buffets", "cakes", "layers", "sliceIds", "components", "revisions", "tableCfgs", "insertHistory", "edits", "multiEdits", "editHistory"];
|
|
29
|
+
export declare const contentTypes: readonly ["buffets", "cakes", "layers", "sliceIds", "components", "revisions", "tableCfgs", "insertHistory", "edits", "multiEdits", "editHistory", "head"];
|
|
30
30
|
export type ContentType = (typeof contentTypes)[number];
|
|
31
31
|
/**
|
|
32
32
|
* An example object using the typedefs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rljson/rljson",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"description": "The RLJSON data format specification",
|
|
5
5
|
"homepage": "https://github.com/rljson/rljson",
|
|
6
6
|
"bugs": "https://github.com/rljson/rljson/issues",
|
|
@@ -21,23 +21,23 @@
|
|
|
21
21
|
"type": "module",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^24.10.1",
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
25
|
-
"@typescript-eslint/parser": "^8.
|
|
26
|
-
"@vitest/coverage-v8": "^4.0.
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
|
25
|
+
"@typescript-eslint/parser": "^8.48.1",
|
|
26
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
27
27
|
"cross-env": "^10.1.0",
|
|
28
28
|
"eslint": "^9.39.1",
|
|
29
|
-
"eslint-plugin-jsdoc": "^61.
|
|
29
|
+
"eslint-plugin-jsdoc": "^61.4.1",
|
|
30
30
|
"eslint-plugin-tsdoc": "^0.5.0",
|
|
31
31
|
"globals": "^16.5.0",
|
|
32
32
|
"jsdoc": "^4.0.5",
|
|
33
33
|
"read-pkg": "^10.0.0",
|
|
34
34
|
"typescript": "~5.9.3",
|
|
35
|
-
"typescript-eslint": "^8.
|
|
36
|
-
"vite": "^7.2.
|
|
37
|
-
"vite-node": "^5.
|
|
35
|
+
"typescript-eslint": "^8.48.1",
|
|
36
|
+
"vite": "^7.2.6",
|
|
37
|
+
"vite-node": "^5.2.0",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4",
|
|
39
39
|
"vite-tsconfig-paths": "^5.1.4",
|
|
40
|
-
"vitest": "^4.0.
|
|
40
|
+
"vitest": "^4.0.15",
|
|
41
41
|
"vitest-dom": "^0.1.1"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|