@rljson/rljson 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rljson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,268 @@
1
+ # Rljson Architecture
2
+
3
+ This document describes the architecture of the Rljson format.
4
+
5
+ ## Table of Contents <!-- omit in toc -->
6
+
7
+ - [What is Rljson?](#what-is-rljson)
8
+ - [Principles](#principles)
9
+ - [JSON](#json)
10
+ - [Relational](#relational)
11
+ - [Normalized](#normalized)
12
+ - [Deeply Hashed](#deeply-hashed)
13
+ - [Immutable](#immutable)
14
+ - [Comparable](#comparable)
15
+ - [Database-Oriented](#database-oriented)
16
+ - [Decentralized](#decentralized)
17
+ - [Concepts](#concepts)
18
+ - [Tables](#tables)
19
+ - [Rows \& Columns](#rows--columns)
20
+ - [Column Data Types](#column-data-types)
21
+ - [Hashes](#hashes)
22
+ - [Linking Tables Using References](#linking-tables-using-references)
23
+ - [Data Types](#data-types)
24
+ - [Properties](#properties)
25
+ - [IdSet](#idset)
26
+ - [Collection](#collection)
27
+ - [Cake](#cake)
28
+ - [Buffet](#buffet)
29
+
30
+ ## What is Rljson?
31
+
32
+ Rljson is a JSON-based exchange format inspired by relational databases,
33
+ designed for efficient synchronization of large datasets across networks.
34
+
35
+ ## Principles
36
+
37
+ ### JSON
38
+
39
+ Rljson uses JSON as its base format.
40
+
41
+ ### Relational
42
+
43
+ Data is organized into normalized tables, similar to relational databases. This
44
+ allows Rljson data to be easily imported into existing database systems.
45
+
46
+ ### Normalized
47
+
48
+ Rljson is designed to transmit normalized, redundancy-free data that can be
49
+ efficiently joined on the client side.
50
+
51
+ ### Deeply Hashed
52
+
53
+ Hashes are added to all data using the `@rljson/hash` package.
54
+
55
+ ### Immutable
56
+
57
+ Hashes serve as primary keys, making datasets immutable by default.
58
+
59
+ ### Comparable
60
+
61
+ Hashes enable easy comparison of Rljson data.
62
+
63
+ ### Database-Oriented
64
+
65
+ Since Rljson follows a database-oriented structure, importing and exporting data
66
+ to and from databases is streamlined.
67
+
68
+ ### Decentralized
69
+
70
+ Rljson hashes can be created without requiring a server, making it well-suited
71
+ for Web 3.0 applications.
72
+
73
+ ## Concepts
74
+
75
+ ### Tables
76
+
77
+ An Rljson file consists of a collection of tables. The table name is the key,
78
+ and the table data is structured as dictionaries:
79
+
80
+ ```json
81
+ {
82
+ "table0": {},
83
+ "table1": {},
84
+ "table2": {}
85
+ }
86
+ ```
87
+
88
+ Each table follows the `RljsonTable` interface, which defines a `_data` property
89
+ containing the table rows and a `_type` property describing the table type:
90
+
91
+ ```json
92
+ {
93
+ "table0": {
94
+ "_type": "properties",
95
+ "_data": []
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Rows & Columns
101
+
102
+ The `_data` section in an Rljson file contains a list of rows. Each row is a
103
+ JSON object that maps column names to values. The example below shows a table
104
+ with two columns, `language` and `greeting`, and two rows for English (`en`) and
105
+ German (`de`):
106
+
107
+ ```json
108
+ {
109
+ "table0": {
110
+ "_data": [
111
+ { "language": "en", "greeting": "Hello" },
112
+ { "language": "de", "greeting": "Hallo" }
113
+ ]
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### Column Data Types
119
+
120
+ Columns can contain any of the Rljson-supported data types: `string | number |
121
+ boolean | null | Json | JsonArray`.
122
+
123
+ ### Hashes
124
+
125
+ Rljson uses hashes to identify and reference data. Using the `hash-in-place`
126
+ (`hip`) method from `@rljson/hash`, hashes are deeply embedded into Rljson data:
127
+
128
+ ```js
129
+ const jsonWithHashes = hip({
130
+ a: {
131
+ _data: [{ a: 10 }],
132
+ _type: 'properties',
133
+ },
134
+ });
135
+ ```
136
+
137
+ This results in:
138
+
139
+ ```json
140
+ {
141
+ "_hash": "D1CtRUBswzGVc1o9yHQKEh",
142
+ "a": {
143
+ "_data": [
144
+ {
145
+ "_hash": "LeFJOCQVgToOfbUuKJQ-GO",
146
+ "a": 10
147
+ }
148
+ ],
149
+ "_hash": "FfCIOVQsrK1g5o5_G-AxP4",
150
+ "_type": "properties"
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Linking Tables Using References
156
+
157
+ Hashes allow tables to be linked using the `Ref` prefix. In the example below,
158
+ table `b` references table `a` using `aRef`:
159
+
160
+ ```json
161
+ {
162
+ "b": {
163
+ "_data": [{ "aRef": "LeFJOCQVgToOfbUuKJQ-GO" }],
164
+ "_type": "properties"
165
+ }
166
+ }
167
+ ```
168
+
169
+ This reference structure enables automated denormalization of JSON data.
170
+
171
+ ## Data Types
172
+
173
+ Rljson provides several core data structures and table types to manage and
174
+ synchronize large datasets.
175
+
176
+ ### Properties
177
+
178
+ `Properties` are the fundamental data concept. A `PropertiesTable` contains
179
+ key-value pairs representing property assignments:
180
+
181
+ ```json
182
+ {
183
+ "sizes": {
184
+ "_type": "properties",
185
+ "_data": [
186
+ { "w": 10, "h": 20 },
187
+ { "w": 30, "h": 40 }
188
+ ]
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### IdSet
194
+
195
+ For efficient management of large collections, item IDs are separated from their
196
+ properties. This allows fetching IDs first and retrieving details later. The
197
+ following `IdSet` defines a set of three IDs:
198
+
199
+ ```json
200
+ {
201
+ "add": ["id0", "id1", "id2"],
202
+ "_hash": "IDS0"
203
+ }
204
+ ```
205
+
206
+ Derived `IdSets` can be created by modifying an existing set:
207
+
208
+ ```json
209
+ {
210
+ "base": "IDS0",
211
+ "add": ["id3", "id4"],
212
+ "remove": ["id0"],
213
+ "_hash": "IDS1"
214
+ }
215
+ ```
216
+
217
+ ### Collection
218
+
219
+ A `Collection` consists of an `IdSet` and a mapping that links item IDs to their
220
+ properties:
221
+
222
+ ```json
223
+ {
224
+ "idSetsTable": "personIds",
225
+ "idSet": "IDS0",
226
+ "properties": "addresses",
227
+ "assign": {
228
+ "id0": "P0HASH",
229
+ "id1": "P1HASH"
230
+ },
231
+ "_hash": "C0HASH"
232
+ }
233
+ ```
234
+
235
+ ### Cake
236
+
237
+ Rljson supports `Cake` as a native data structure:
238
+
239
+ - A `Cake` consists of layers, each representing a collection of items (slices).
240
+ - All layers share the same item IDs (slice structure).
241
+ - Each layer assigns different properties to the same items.
242
+
243
+ ```json
244
+ {
245
+ "itemIdsTable": "ingredientIds",
246
+ "itemIds": "IDS1",
247
+ "layersTable": "HASH",
248
+ "assign": {
249
+ "base": "HASH15",
250
+ "cherries": "HASH16",
251
+ "creme": "HASH17"
252
+ }
253
+ }
254
+ ```
255
+
256
+ ### Buffet
257
+
258
+ A `Buffet` is a heterogeneous collection of different but related items, such as
259
+ cakes, collections, or properties:
260
+
261
+ ```json
262
+ {
263
+ "items": [
264
+ { "table": "drinks", "ref": "HASH20" },
265
+ { "table": "cakes", "ref": "HASH21" }
266
+ ]
267
+ }
268
+ ```
package/README.blog.md ADDED
@@ -0,0 +1,3 @@
1
+ # Blog
2
+
3
+ Add latest posts at the end.
@@ -0,0 +1,151 @@
1
+ # Contributors
2
+
3
+ ## Important
4
+
5
+ ⚠️ IMPORTANT: On `Windows, please checkout the repo on drive C`.
6
+ There is a bug in the Vscode vitest extension v 1.14.4, making debugging tests
7
+ not work. <https://github.com/vitest-dev/vscode/issues/548>
8
+ Please check from time to time, if the issue is fixed and remove this hint.
9
+
10
+ ## Report issues
11
+
12
+ Visit <https://github.com/rljson/rljson/issues>
13
+
14
+ Check if there is already an issue for your problem
15
+
16
+ If no, report the issue
17
+
18
+ ## Install pnpm
19
+
20
+ Windows:
21
+
22
+ ```bash
23
+ corepack enable pnpm
24
+ ```
25
+
26
+ Mac:
27
+
28
+ ```bash
29
+ sudo corepack enable pnpm
30
+ ```
31
+
32
+ ## Check out
33
+
34
+ ```bash
35
+ mkdir rljson
36
+ cd rljson
37
+ git clone https://github.com/rljson/rljson.git
38
+ cd rljson
39
+ ```
40
+
41
+ ## Install dependencies
42
+
43
+ ```bash
44
+ npm install
45
+ ```
46
+
47
+ ## Run the tests
48
+
49
+ ```bash
50
+ npm run test
51
+ ```
52
+
53
+ ## Build the package
54
+
55
+ ```bash
56
+ npm run build
57
+ ```
58
+
59
+ ## Publish the package
60
+
61
+ Open `package.json`
62
+
63
+ Increase `version`
64
+
65
+ Make sure all dependencies are listed in `peerDependencies`
66
+
67
+ Make sure no file references are contained
68
+
69
+ Open `vite.config.mts` right beside `package.json`
70
+
71
+ Make sure all `peerDependencies` are listed in `rollupOptions/external`
72
+
73
+ Compile typescript:
74
+
75
+ ```bash
76
+ npm run build
77
+ ```
78
+
79
+ Make publish dry-run
80
+
81
+ ```bash
82
+ npm publish --access=public --dry-run
83
+ ```
84
+
85
+ Check the changes to uploaded
86
+
87
+ Publish the package
88
+
89
+ ```bash
90
+ npm publish --access=public
91
+ ```
92
+
93
+ ## Architecture
94
+
95
+ Reade [README.architecture.md](./README.architecture.md) to get an overview
96
+ of the package's architecture.
97
+
98
+ ## Install Vscode extensions
99
+
100
+ Open this project in `vscode`.
101
+
102
+ Press `Cmd+Shift+P`.
103
+
104
+ Type `Extensions: Show Recommended Extensions` and press `Enter`.
105
+
106
+ The recommended extensions will be shown.
107
+
108
+ Make sure, all recommended extensions are shown.
109
+
110
+ ## Uninstall all test extensions, e.g. Jest or Jasmine
111
+
112
+ Jest or Jasmine extensions conflict with the `Vitest` extension used for this
113
+ project.
114
+
115
+ Uninstall them, if you have installed them.
116
+
117
+ ## Debug tests
118
+
119
+ In Vscode: At the `left side bar` click on the `Test tube` icon to open the `Test explorer`.
120
+
121
+ At the `top`, click on the `refresh` icon to show update the tests.
122
+
123
+ Open a test file (`*.spec.ts`)
124
+
125
+ Set a breakpoint.
126
+
127
+ Press `alt` and click on the play button left beside the test.
128
+
129
+ Execution should stop at the breakpoint.
130
+
131
+ ## Update goldens
132
+
133
+ In various tests we are creating golden files, that are reference files that
134
+ are compared against the files created in the tests.
135
+
136
+ If change is detected, the fest fail.
137
+
138
+ An example is `test/goldens/README.md` which is compared against
139
+ `dist/README.md`.
140
+
141
+ If the changes are desired, update the golden files:
142
+
143
+ Open `update-goldens.ts`
144
+
145
+ Set `export const updateGoldens` to `true`
146
+
147
+ Run tests again.
148
+
149
+ Set `export const updateGoldens` to `false`.
150
+
151
+ Run tests again.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @rljson/rljson
2
+
3
+ The RLJSON data format specification
4
+
5
+ ## Users
6
+
7
+ | File | Purpose |
8
+ | ------------------------------------ | --------------------------- |
9
+ | [README.public.md](README.public.md) | Install and use the package |
10
+
11
+ ## Contributors
12
+
13
+ | File | Purpose |
14
+ | ------------------------------------------------ | ----------------------------- |
15
+ | [README.contributors.md](README.contributors.md) | Run, debug, build and publish |
16
+ | [README.architecture.md](README.architecture.md) | Software architecture guide |
17
+ | [README.trouble.md](README.trouble.md) | Errors & solutions |
18
+ | [README.blog.md](README.blog.md) | Blog |
@@ -0,0 +1,7 @@
1
+ # @rljson/
2
+
3
+ Todo: Add description here
4
+
5
+ ## Example
6
+
7
+ [src/example.ts](src/example.ts)
@@ -0,0 +1,36 @@
1
+ <!--
2
+
3
+ -->
4
+
5
+ # Trouble shooting
6
+
7
+ ## Table of contents <!-- omit in toc -->
8
+
9
+ - [Vscode Windows: Debugging is not working](#vscode-windows-debugging-is-not-working)
10
+ - [GitHub actions: Cannot find module @rollup/rollup-linux-x64-gnu](#github-actions-cannot-find-module-rolluprollup-linux-x64-gnu)
11
+
12
+ ## Vscode Windows: Debugging is not working
13
+
14
+ Date: 2025-03-08
15
+
16
+ ⚠️ IMPORTANT: On Windows, please check out the repo on drive C. There is a bug
17
+ in the VS Code Vitest extension (v1.14.4), which prevents test debugging from
18
+ working: <https://github.com/vitest-dev/vscode/issues/548> Please check from
19
+ time to time if the issue has been fixed and remove this note once it is
20
+ resolved.
21
+
22
+ ## GitHub actions: Cannot find module @rollup/rollup-linux-x64-gnu
23
+
24
+ ⚠️ Error: Cannot find module @rollup/rollup-linux-x64-gnu. npm has a bug related to
25
+ optional dependencies (<https://github.com/npm/cli/issues/4828>). Please try `npm
26
+ i` again after removing both package-lock.json and node_modules directory.
27
+
28
+ Solution:
29
+
30
+ ```bash
31
+ rm -rf node_modules
32
+ rm package-lock.json
33
+ npm install
34
+ ```
35
+
36
+ Then push `package-lock.yaml` again
@@ -0,0 +1,268 @@
1
+ # Rljson Architecture
2
+
3
+ This document describes the architecture of the Rljson format.
4
+
5
+ ## Table of Contents <!-- omit in toc -->
6
+
7
+ - [What is Rljson?](#what-is-rljson)
8
+ - [Principles](#principles)
9
+ - [JSON](#json)
10
+ - [Relational](#relational)
11
+ - [Normalized](#normalized)
12
+ - [Deeply Hashed](#deeply-hashed)
13
+ - [Immutable](#immutable)
14
+ - [Comparable](#comparable)
15
+ - [Database-Oriented](#database-oriented)
16
+ - [Decentralized](#decentralized)
17
+ - [Concepts](#concepts)
18
+ - [Tables](#tables)
19
+ - [Rows \& Columns](#rows--columns)
20
+ - [Column Data Types](#column-data-types)
21
+ - [Hashes](#hashes)
22
+ - [Linking Tables Using References](#linking-tables-using-references)
23
+ - [Data Types](#data-types)
24
+ - [Properties](#properties)
25
+ - [IdSet](#idset)
26
+ - [Collection](#collection)
27
+ - [Cake](#cake)
28
+ - [Buffet](#buffet)
29
+
30
+ ## What is Rljson?
31
+
32
+ Rljson is a JSON-based exchange format inspired by relational databases,
33
+ designed for efficient synchronization of large datasets across networks.
34
+
35
+ ## Principles
36
+
37
+ ### JSON
38
+
39
+ Rljson uses JSON as its base format.
40
+
41
+ ### Relational
42
+
43
+ Data is organized into normalized tables, similar to relational databases. This
44
+ allows Rljson data to be easily imported into existing database systems.
45
+
46
+ ### Normalized
47
+
48
+ Rljson is designed to transmit normalized, redundancy-free data that can be
49
+ efficiently joined on the client side.
50
+
51
+ ### Deeply Hashed
52
+
53
+ Hashes are added to all data using the `@rljson/hash` package.
54
+
55
+ ### Immutable
56
+
57
+ Hashes serve as primary keys, making datasets immutable by default.
58
+
59
+ ### Comparable
60
+
61
+ Hashes enable easy comparison of Rljson data.
62
+
63
+ ### Database-Oriented
64
+
65
+ Since Rljson follows a database-oriented structure, importing and exporting data
66
+ to and from databases is streamlined.
67
+
68
+ ### Decentralized
69
+
70
+ Rljson hashes can be created without requiring a server, making it well-suited
71
+ for Web 3.0 applications.
72
+
73
+ ## Concepts
74
+
75
+ ### Tables
76
+
77
+ An Rljson file consists of a collection of tables. The table name is the key,
78
+ and the table data is structured as dictionaries:
79
+
80
+ ```json
81
+ {
82
+ "table0": {},
83
+ "table1": {},
84
+ "table2": {}
85
+ }
86
+ ```
87
+
88
+ Each table follows the `RljsonTable` interface, which defines a `_data` property
89
+ containing the table rows and a `_type` property describing the table type:
90
+
91
+ ```json
92
+ {
93
+ "table0": {
94
+ "_type": "properties",
95
+ "_data": []
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Rows & Columns
101
+
102
+ The `_data` section in an Rljson file contains a list of rows. Each row is a
103
+ JSON object that maps column names to values. The example below shows a table
104
+ with two columns, `language` and `greeting`, and two rows for English (`en`) and
105
+ German (`de`):
106
+
107
+ ```json
108
+ {
109
+ "table0": {
110
+ "_data": [
111
+ { "language": "en", "greeting": "Hello" },
112
+ { "language": "de", "greeting": "Hallo" }
113
+ ]
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### Column Data Types
119
+
120
+ Columns can contain any of the Rljson-supported data types: `string | number |
121
+ boolean | null | Json | JsonArray`.
122
+
123
+ ### Hashes
124
+
125
+ Rljson uses hashes to identify and reference data. Using the `hash-in-place`
126
+ (`hip`) method from `@rljson/hash`, hashes are deeply embedded into Rljson data:
127
+
128
+ ```js
129
+ const jsonWithHashes = hip({
130
+ a: {
131
+ _data: [{ a: 10 }],
132
+ _type: 'properties',
133
+ },
134
+ });
135
+ ```
136
+
137
+ This results in:
138
+
139
+ ```json
140
+ {
141
+ "_hash": "D1CtRUBswzGVc1o9yHQKEh",
142
+ "a": {
143
+ "_data": [
144
+ {
145
+ "_hash": "LeFJOCQVgToOfbUuKJQ-GO",
146
+ "a": 10
147
+ }
148
+ ],
149
+ "_hash": "FfCIOVQsrK1g5o5_G-AxP4",
150
+ "_type": "properties"
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Linking Tables Using References
156
+
157
+ Hashes allow tables to be linked using the `Ref` prefix. In the example below,
158
+ table `b` references table `a` using `aRef`:
159
+
160
+ ```json
161
+ {
162
+ "b": {
163
+ "_data": [{ "aRef": "LeFJOCQVgToOfbUuKJQ-GO" }],
164
+ "_type": "properties"
165
+ }
166
+ }
167
+ ```
168
+
169
+ This reference structure enables automated denormalization of JSON data.
170
+
171
+ ## Data Types
172
+
173
+ Rljson provides several core data structures and table types to manage and
174
+ synchronize large datasets.
175
+
176
+ ### Properties
177
+
178
+ `Properties` are the fundamental data concept. A `PropertiesTable` contains
179
+ key-value pairs representing property assignments:
180
+
181
+ ```json
182
+ {
183
+ "sizes": {
184
+ "_type": "properties",
185
+ "_data": [
186
+ { "w": 10, "h": 20 },
187
+ { "w": 30, "h": 40 }
188
+ ]
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### IdSet
194
+
195
+ For efficient management of large collections, item IDs are separated from their
196
+ properties. This allows fetching IDs first and retrieving details later. The
197
+ following `IdSet` defines a set of three IDs:
198
+
199
+ ```json
200
+ {
201
+ "add": ["id0", "id1", "id2"],
202
+ "_hash": "IDS0"
203
+ }
204
+ ```
205
+
206
+ Derived `IdSets` can be created by modifying an existing set:
207
+
208
+ ```json
209
+ {
210
+ "base": "IDS0",
211
+ "add": ["id3", "id4"],
212
+ "remove": ["id0"],
213
+ "_hash": "IDS1"
214
+ }
215
+ ```
216
+
217
+ ### Collection
218
+
219
+ A `Collection` consists of an `IdSet` and a mapping that links item IDs to their
220
+ properties:
221
+
222
+ ```json
223
+ {
224
+ "idSetsTable": "personIds",
225
+ "idSet": "IDS0",
226
+ "properties": "addresses",
227
+ "assign": {
228
+ "id0": "P0HASH",
229
+ "id1": "P1HASH"
230
+ },
231
+ "_hash": "C0HASH"
232
+ }
233
+ ```
234
+
235
+ ### Cake
236
+
237
+ Rljson supports `Cake` as a native data structure:
238
+
239
+ - A `Cake` consists of layers, each representing a collection of items (slices).
240
+ - All layers share the same item IDs (slice structure).
241
+ - Each layer assigns different properties to the same items.
242
+
243
+ ```json
244
+ {
245
+ "itemIdsTable": "ingredientIds",
246
+ "itemIds": "IDS1",
247
+ "layersTable": "HASH",
248
+ "assign": {
249
+ "base": "HASH15",
250
+ "cherries": "HASH16",
251
+ "creme": "HASH17"
252
+ }
253
+ }
254
+ ```
255
+
256
+ ### Buffet
257
+
258
+ A `Buffet` is a heterogeneous collection of different but related items, such as
259
+ cakes, collections, or properties:
260
+
261
+ ```json
262
+ {
263
+ "items": [
264
+ { "table": "drinks", "ref": "HASH20" },
265
+ { "table": "cakes", "ref": "HASH21" }
266
+ ]
267
+ }
268
+ ```
@@ -0,0 +1,3 @@
1
+ # Blog
2
+
3
+ Add latest posts at the end.
@@ -0,0 +1,151 @@
1
+ # Contributors
2
+
3
+ ## Important
4
+
5
+ ⚠️ IMPORTANT: On `Windows, please checkout the repo on drive C`.
6
+ There is a bug in the Vscode vitest extension v 1.14.4, making debugging tests
7
+ not work. <https://github.com/vitest-dev/vscode/issues/548>
8
+ Please check from time to time, if the issue is fixed and remove this hint.
9
+
10
+ ## Report issues
11
+
12
+ Visit <https://github.com/rljson/rljson/issues>
13
+
14
+ Check if there is already an issue for your problem
15
+
16
+ If no, report the issue
17
+
18
+ ## Install pnpm
19
+
20
+ Windows:
21
+
22
+ ```bash
23
+ corepack enable pnpm
24
+ ```
25
+
26
+ Mac:
27
+
28
+ ```bash
29
+ sudo corepack enable pnpm
30
+ ```
31
+
32
+ ## Check out
33
+
34
+ ```bash
35
+ mkdir rljson
36
+ cd rljson
37
+ git clone https://github.com/rljson/rljson.git
38
+ cd rljson
39
+ ```
40
+
41
+ ## Install dependencies
42
+
43
+ ```bash
44
+ npm install
45
+ ```
46
+
47
+ ## Run the tests
48
+
49
+ ```bash
50
+ npm run test
51
+ ```
52
+
53
+ ## Build the package
54
+
55
+ ```bash
56
+ npm run build
57
+ ```
58
+
59
+ ## Publish the package
60
+
61
+ Open `package.json`
62
+
63
+ Increase `version`
64
+
65
+ Make sure all dependencies are listed in `peerDependencies`
66
+
67
+ Make sure no file references are contained
68
+
69
+ Open `vite.config.mts` right beside `package.json`
70
+
71
+ Make sure all `peerDependencies` are listed in `rollupOptions/external`
72
+
73
+ Compile typescript:
74
+
75
+ ```bash
76
+ npm run build
77
+ ```
78
+
79
+ Make publish dry-run
80
+
81
+ ```bash
82
+ npm publish --access=public --dry-run
83
+ ```
84
+
85
+ Check the changes to uploaded
86
+
87
+ Publish the package
88
+
89
+ ```bash
90
+ npm publish --access=public
91
+ ```
92
+
93
+ ## Architecture
94
+
95
+ Reade [README.architecture.md](./README.architecture.md) to get an overview
96
+ of the package's architecture.
97
+
98
+ ## Install Vscode extensions
99
+
100
+ Open this project in `vscode`.
101
+
102
+ Press `Cmd+Shift+P`.
103
+
104
+ Type `Extensions: Show Recommended Extensions` and press `Enter`.
105
+
106
+ The recommended extensions will be shown.
107
+
108
+ Make sure, all recommended extensions are shown.
109
+
110
+ ## Uninstall all test extensions, e.g. Jest or Jasmine
111
+
112
+ Jest or Jasmine extensions conflict with the `Vitest` extension used for this
113
+ project.
114
+
115
+ Uninstall them, if you have installed them.
116
+
117
+ ## Debug tests
118
+
119
+ In Vscode: At the `left side bar` click on the `Test tube` icon to open the `Test explorer`.
120
+
121
+ At the `top`, click on the `refresh` icon to show update the tests.
122
+
123
+ Open a test file (`*.spec.ts`)
124
+
125
+ Set a breakpoint.
126
+
127
+ Press `alt` and click on the play button left beside the test.
128
+
129
+ Execution should stop at the breakpoint.
130
+
131
+ ## Update goldens
132
+
133
+ In various tests we are creating golden files, that are reference files that
134
+ are compared against the files created in the tests.
135
+
136
+ If change is detected, the fest fail.
137
+
138
+ An example is `test/goldens/README.md` which is compared against
139
+ `dist/README.md`.
140
+
141
+ If the changes are desired, update the golden files:
142
+
143
+ Open `update-goldens.ts`
144
+
145
+ Set `export const updateGoldens` to `true`
146
+
147
+ Run tests again.
148
+
149
+ Set `export const updateGoldens` to `false`.
150
+
151
+ Run tests again.
package/dist/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @rljson/rljson
2
+
3
+ The RLJSON data format specification
4
+
5
+ ## Users
6
+
7
+ | File | Purpose |
8
+ | ------------------------------------ | --------------------------- |
9
+ | [README.public.md](README.public.md) | Install and use the package |
10
+
11
+ ## Contributors
12
+
13
+ | File | Purpose |
14
+ | ------------------------------------------------ | ----------------------------- |
15
+ | [README.contributors.md](README.contributors.md) | Run, debug, build and publish |
16
+ | [README.architecture.md](README.architecture.md) | Software architecture guide |
17
+ | [README.trouble.md](README.trouble.md) | Errors & solutions |
18
+ | [README.blog.md](README.blog.md) | Blog |
@@ -0,0 +1,7 @@
1
+ # @rljson/
2
+
3
+ Todo: Add description here
4
+
5
+ ## Example
6
+
7
+ [src/example.ts](src/example.ts)
@@ -0,0 +1,36 @@
1
+ <!--
2
+
3
+ -->
4
+
5
+ # Trouble shooting
6
+
7
+ ## Table of contents <!-- omit in toc -->
8
+
9
+ - [Vscode Windows: Debugging is not working](#vscode-windows-debugging-is-not-working)
10
+ - [GitHub actions: Cannot find module @rollup/rollup-linux-x64-gnu](#github-actions-cannot-find-module-rolluprollup-linux-x64-gnu)
11
+
12
+ ## Vscode Windows: Debugging is not working
13
+
14
+ Date: 2025-03-08
15
+
16
+ ⚠️ IMPORTANT: On Windows, please check out the repo on drive C. There is a bug
17
+ in the VS Code Vitest extension (v1.14.4), which prevents test debugging from
18
+ working: <https://github.com/vitest-dev/vscode/issues/548> Please check from
19
+ time to time if the issue has been fixed and remove this note once it is
20
+ resolved.
21
+
22
+ ## GitHub actions: Cannot find module @rollup/rollup-linux-x64-gnu
23
+
24
+ ⚠️ Error: Cannot find module @rollup/rollup-linux-x64-gnu. npm has a bug related to
25
+ optional dependencies (<https://github.com/npm/cli/issues/4828>). Please try `npm
26
+ i` again after removing both package-lock.json and node_modules directory.
27
+
28
+ Solution:
29
+
30
+ ```bash
31
+ rm -rf node_modules
32
+ rm package-lock.json
33
+ npm install
34
+ ```
35
+
36
+ Then push `package-lock.yaml` again
@@ -0,0 +1,4 @@
1
+ /**
2
+ * The example function demonstrates how the package works
3
+ */
4
+ export declare const example: () => void;
@@ -0,0 +1 @@
1
+ export { type Rljson } from './rljson.ts';
@@ -0,0 +1,168 @@
1
+ import { Json, JsonValue } from '@rljson/json';
2
+ /**
3
+ * A ref is a hash that references to another element
4
+ */
5
+ export type Ref = string;
6
+ /**
7
+ * An `id` is a *user defined* name or identifier of an item.
8
+ * It exists in parallel with the auto generated `_hash`.
9
+ */
10
+ export type ItemId = string;
11
+ /**
12
+ * A table id reference to a table. The table ids are used as keys in the top
13
+ * level structure of an Rljson data object.
14
+ */
15
+ export type TableName = ItemId;
16
+ /**
17
+ * Types of tables that can be stored in an Rljson object
18
+ *
19
+ * - `buffets` Tables containing buffets
20
+ * - `cakes` Tables containing cakes
21
+ * - `collections` Tables containing collections
22
+ * - `ids` Tables containing item ids
23
+ * - `properties` Tables containing item properties
24
+ */
25
+ export type TableType = 'buffet' | 'cake' | 'collection' | 'ids' | 'properties';
26
+ /** A table in the rljson format */
27
+ export interface RljsonTable<Data extends Json, Type extends TableType> extends Json {
28
+ /** The data rows of the table */
29
+ _data: Data[];
30
+ /** The type of the table */
31
+ _type: Type;
32
+ }
33
+ /**
34
+ * A reference to a properties row in a properties table
35
+ */
36
+ export type PropertiesRef = Ref;
37
+ /**
38
+ * A table containing item properties
39
+ */
40
+ export type PropertiesTable = RljsonTable<Json, 'properties'>;
41
+ /**
42
+ * An IdSetRef is a hash pointing to an Ids
43
+ */
44
+ export type IdSetRef = Ref;
45
+ /**
46
+ * An Ids manages list of item ids
47
+ */
48
+ export interface IdSet extends Json {
49
+ /**
50
+ * The hash of another item id list which is extended by this one.
51
+ * Must be empty or null, when the list is the root.
52
+ */
53
+ base: IdSetRef | null;
54
+ /**
55
+ * The item ids added to base
56
+ */
57
+ add: ItemId[];
58
+ /**
59
+ * The item ids removed from base
60
+ */
61
+ remove: ItemId[];
62
+ }
63
+ /**
64
+ * A table containing item ids
65
+ */
66
+ export type IdSetsTable = RljsonTable<IdSet, 'ids'>;
67
+ /**
68
+ * A CollectionRef is a hash pointing to a collection
69
+ */
70
+ export type CollectionRef = Ref;
71
+ /**
72
+ * A collection assigns properties to item ids
73
+ */
74
+ export interface Collection extends Json {
75
+ /**
76
+ * `base` an optional base collection that is extended by this collection
77
+ */
78
+ base: CollectionRef | null;
79
+ /**
80
+ * The table containing the item set of this collection
81
+ */
82
+ idSetsTable: TableName;
83
+ /**
84
+ * A reference to the ids of the items the collection is based on
85
+ */
86
+ idSet: IdSetRef;
87
+ /**
88
+ * The table containing the properties assigned to the items of this collection
89
+ */
90
+ properties: TableName;
91
+ /**
92
+ * Assign properties to each item of the collection.
93
+ */
94
+ assign: Record<ItemId, PropertiesRef>;
95
+ }
96
+ /**
97
+ * A table containing collections
98
+ */
99
+ export type CollectionsTable = RljsonTable<Collection, 'collection'>;
100
+ /**
101
+ * A `CakeLayerId` assigns an id or name to a cake layer
102
+ */
103
+ export type CakeLayerId = ItemId;
104
+ /**
105
+ * A `CakeLayerIds` is a set of cake layer ids / cake layer names
106
+ */
107
+ export type CakeLayerIds = IdSet;
108
+ /**
109
+ * A cake is a collection of layers.
110
+ *
111
+ * A layer is a collection of items.
112
+ * All layers of a cake refer to the same items.
113
+ */
114
+ export interface Cake extends Json {
115
+ /**
116
+ * The table containing the item ids of the cake
117
+ */
118
+ itemIdsTable: TableName;
119
+ /**
120
+ * All layers of a cake share the same item ids.
121
+ */
122
+ itemIds: IdSetRef;
123
+ /**
124
+ * The table containing the layers of this cake
125
+ */
126
+ layersTable: TableName;
127
+ /**
128
+ * Assigns a collection to each layer of the cake.
129
+ */
130
+ layers: {
131
+ [layerId: CakeLayerId]: CollectionRef;
132
+ };
133
+ }
134
+ /**
135
+ * A table containing cakes
136
+ */
137
+ export type CakesTable = RljsonTable<Cake, 'cake'>;
138
+ /**
139
+ * A buffet id is a name or id of a buffet
140
+ */
141
+ export type BuffetId = ItemId;
142
+ /**
143
+ * A buffet is a collection of arbitrary but related items, e.g. cakes,
144
+ * collections, or items.
145
+ */
146
+ export interface Buffet extends Json {
147
+ /**
148
+ * The items of the buffet
149
+ */
150
+ items: Array<{
151
+ table: TableName;
152
+ ref: Ref;
153
+ [key: string]: JsonValue;
154
+ }>;
155
+ }
156
+ /**
157
+ * A table containing buffets
158
+ */
159
+ export type BuffetsTable = RljsonTable<Buffet, 'buffet'>;
160
+ /**
161
+ * One of the supported Rljson table types
162
+ */
163
+ export type RljsonTableType = BuffetsTable | PropertiesTable | CollectionsTable | IdSetsTable | CakesTable;
164
+ /** The rljson data format */
165
+ export interface Rljson extends Json {
166
+ [tableId: TableName]: RljsonTableType | string;
167
+ }
168
+ export declare const exampleRljson: () => Rljson;
package/dist/rljson.js ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,18 @@
1
+ // @license
2
+ // Copyright (c) 2025 Rljson
3
+ //
4
+ // Use of this source code is governed by terms that can be
5
+ // found in the LICENSE file in the root of this package.
6
+
7
+ import { exampleRljson } from './rljson.ts';
8
+
9
+ /**
10
+ * The example function demonstrates how the package works
11
+ */
12
+ export const example = () => {
13
+ const print = console.log;
14
+ const stringify = JSON.stringify;
15
+
16
+ const rljson = exampleRljson();
17
+ print(stringify(rljson, null, 2));
18
+ };
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@rljson/rljson",
3
+ "version": "0.0.1",
4
+ "packageManager": "pnpm@10.6.2",
5
+ "description": "The RLJSON data format specification",
6
+ "homepage": "https://github.com/rljson/rljson",
7
+ "bugs": "https://github.com/rljson/rljson/issues",
8
+ "private": false,
9
+ "license": "MIT",
10
+ "engines": {
11
+ "node": ">=22.14.0"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/rljson/rljson.git"
16
+ },
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "type": "module",
23
+ "scripts": {
24
+ "build": "npx vite build && tsc && cp README* dist && mkdir dist/src && cp src/example.ts dist/src",
25
+ "test": "npx vitest run --coverage && npm run lint",
26
+ "prebuild": "npm run test",
27
+ "prepublishOnly": "npm run build && npm run test",
28
+ "lint": "npx eslint",
29
+ "updateGoldens": "cross-env UPDATE_GOLDENS=true npm test"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.13.10",
33
+ "@typescript-eslint/eslint-plugin": "^8.26.1",
34
+ "@typescript-eslint/parser": "^8.26.1",
35
+ "@vitest/coverage-v8": "^3.0.8",
36
+ "cross-env": "^7.0.3",
37
+ "eslint": "^9.22.0",
38
+ "eslint-plugin-jsdoc": "^50.6.3",
39
+ "eslint-plugin-tsdoc": "^0.4.0",
40
+ "globals": "^16.0.0",
41
+ "jsdoc": "^4.0.4",
42
+ "typescript": "~5.8.2",
43
+ "typescript-eslint": "^8.26.1",
44
+ "vite": "^6.2.1",
45
+ "vite-node": "^3.0.8",
46
+ "vite-plugin-dts": "^4.5.3",
47
+ "vite-tsconfig-paths": "^5.1.4",
48
+ "vitest": "^3.0.8",
49
+ "vitest-dom": "^0.1.1"
50
+ },
51
+ "peerDependencies": {
52
+ "@rljson/hash": "^0.0.5",
53
+ "@rljson/json": "^0.0.4"
54
+ },
55
+ "pnpm": {
56
+ "onlyBuiltDependencies": [
57
+ "esbuild"
58
+ ]
59
+ }
60
+ }