@ng-org/orm 0.1.2-alpha.1 → 0.1.2-alpha.10

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.
Files changed (89) hide show
  1. package/README.md +151 -230
  2. package/dist/connector/applyPatches.d.ts +19 -49
  3. package/dist/connector/applyPatches.d.ts.map +1 -1
  4. package/dist/connector/applyPatches.js +57 -58
  5. package/dist/connector/discrete/discreteOrmSubscriptionHandler.d.ts +168 -0
  6. package/dist/connector/discrete/discreteOrmSubscriptionHandler.d.ts.map +1 -0
  7. package/dist/connector/discrete/discreteOrmSubscriptionHandler.js +309 -0
  8. package/dist/connector/getObjects.d.ts +11 -0
  9. package/dist/connector/getObjects.d.ts.map +1 -0
  10. package/dist/connector/getObjects.js +26 -0
  11. package/dist/connector/initNg.d.ts +33 -2
  12. package/dist/connector/initNg.d.ts.map +1 -1
  13. package/dist/connector/initNg.js +30 -0
  14. package/dist/connector/insertObject.d.ts +9 -0
  15. package/dist/connector/insertObject.d.ts.map +1 -0
  16. package/dist/connector/insertObject.js +24 -0
  17. package/dist/connector/ormSubscriptionHandler.d.ts +167 -0
  18. package/dist/connector/ormSubscriptionHandler.d.ts.map +1 -0
  19. package/dist/connector/ormSubscriptionHandler.js +400 -0
  20. package/dist/connector/utils.d.ts +17 -0
  21. package/dist/connector/utils.d.ts.map +1 -0
  22. package/dist/connector/utils.js +68 -0
  23. package/dist/frontendAdapters/react/index.d.ts +2 -1
  24. package/dist/frontendAdapters/react/index.d.ts.map +1 -1
  25. package/dist/frontendAdapters/react/index.js +2 -1
  26. package/dist/frontendAdapters/react/useDiscrete.d.ts +104 -0
  27. package/dist/frontendAdapters/react/useDiscrete.d.ts.map +1 -0
  28. package/dist/frontendAdapters/react/useDiscrete.js +151 -0
  29. package/dist/frontendAdapters/react/useShape.d.ts +69 -2
  30. package/dist/frontendAdapters/react/useShape.d.ts.map +1 -1
  31. package/dist/frontendAdapters/react/useShape.js +89 -8
  32. package/dist/frontendAdapters/svelte/index.d.ts +2 -1
  33. package/dist/frontendAdapters/svelte/index.d.ts.map +1 -1
  34. package/dist/frontendAdapters/svelte/index.js +2 -1
  35. package/dist/frontendAdapters/svelte/useDiscrete.svelte.d.ts +94 -0
  36. package/dist/frontendAdapters/svelte/useDiscrete.svelte.d.ts.map +1 -0
  37. package/dist/frontendAdapters/svelte/useDiscrete.svelte.js +137 -0
  38. package/dist/frontendAdapters/svelte/useShape.svelte.d.ts +79 -10
  39. package/dist/frontendAdapters/svelte/useShape.svelte.d.ts.map +1 -1
  40. package/dist/frontendAdapters/svelte/useShape.svelte.js +88 -9
  41. package/dist/frontendAdapters/svelte4/index.d.ts +5 -0
  42. package/dist/frontendAdapters/svelte4/index.d.ts.map +1 -0
  43. package/dist/{connector/createSignalObjectForShape.js → frontendAdapters/svelte4/index.js} +3 -15
  44. package/dist/frontendAdapters/svelte4/useDiscrete.svelte.d.ts +84 -0
  45. package/dist/frontendAdapters/svelte4/useDiscrete.svelte.d.ts.map +1 -0
  46. package/dist/frontendAdapters/svelte4/useDiscrete.svelte.js +126 -0
  47. package/dist/frontendAdapters/svelte4/useShape.svelte.d.ts +77 -0
  48. package/dist/frontendAdapters/svelte4/useShape.svelte.d.ts.map +1 -0
  49. package/dist/frontendAdapters/svelte4/useShape.svelte.js +91 -0
  50. package/dist/frontendAdapters/utils.d.ts +2 -0
  51. package/dist/frontendAdapters/utils.d.ts.map +1 -0
  52. package/dist/frontendAdapters/utils.js +14 -0
  53. package/dist/frontendAdapters/vue/index.d.ts +2 -1
  54. package/dist/frontendAdapters/vue/index.d.ts.map +1 -1
  55. package/dist/frontendAdapters/vue/index.js +2 -1
  56. package/dist/frontendAdapters/vue/useDiscrete.d.ts +99 -0
  57. package/dist/frontendAdapters/vue/useDiscrete.d.ts.map +1 -0
  58. package/dist/frontendAdapters/vue/useDiscrete.js +123 -0
  59. package/dist/frontendAdapters/vue/useShape.d.ts +73 -2
  60. package/dist/frontendAdapters/vue/useShape.d.ts.map +1 -1
  61. package/dist/frontendAdapters/vue/useShape.js +79 -4
  62. package/dist/index.d.ts +13 -6
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +21 -6
  65. package/dist/types.d.ts +63 -11
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +13 -1
  68. package/package.json +37 -48
  69. package/dist/connector/applyPatches.test.d.ts +0 -2
  70. package/dist/connector/applyPatches.test.d.ts.map +0 -1
  71. package/dist/connector/applyPatches.test.js +0 -772
  72. package/dist/connector/createSignalObjectForShape.d.ts +0 -14
  73. package/dist/connector/createSignalObjectForShape.d.ts.map +0 -1
  74. package/dist/connector/ormConnectionHandler.d.ts +0 -47
  75. package/dist/connector/ormConnectionHandler.d.ts.map +0 -1
  76. package/dist/connector/ormConnectionHandler.js +0 -240
  77. package/src/connector/applyPatches.test.ts +0 -842
  78. package/src/connector/applyPatches.ts +0 -404
  79. package/src/connector/createSignalObjectForShape.ts +0 -35
  80. package/src/connector/initNg.ts +0 -30
  81. package/src/connector/ormConnectionHandler.ts +0 -300
  82. package/src/frontendAdapters/react/index.ts +0 -2
  83. package/src/frontendAdapters/react/useShape.ts +0 -36
  84. package/src/frontendAdapters/svelte/index.ts +0 -2
  85. package/src/frontendAdapters/svelte/useShape.svelte.ts +0 -46
  86. package/src/frontendAdapters/vue/index.ts +0 -2
  87. package/src/frontendAdapters/vue/useShape.ts +0 -33
  88. package/src/index.ts +0 -14
  89. package/src/types.ts +0 -26
package/README.md CHANGED
@@ -1,44 +1,45 @@
1
- # @ng-org/orm
1
+ # NextGraph ORM SDK
2
2
 
3
- Reactive ORM library for NextGraph use typed, reactive objects that automatically sync to NextGraph's encrypted, local-first storage.
3
+ Reactive ORM library for NextGraph: use reactive (typed) objects that automatically sync to NextGraph's encrypted, local-first storage.
4
4
 
5
- For a walk-through, you can see the the [expense-tracker example app](https://git.nextgraph.org/NextGraph/expense-tracker) which shows
6
- - React, Vue, and Svelte frontends sharing data
7
- - SHEX schema definitions
8
- - CRUD operations
9
- - Cross-framework real-time sync
5
+ For a walk-through you can see the the expense-tracker example apps for [discrete JSON documents](https://git.nextgraph.org/NextGraph/expense-tracker-discrete) or [typed graph documents](https://git.nextgraph.org/NextGraph/expense-tracker-graph).
6
+
7
+ ## Reference documentation
8
+
9
+ [Reference documentation is available here on docs.nextgraph.org](https://docs.nextgraph.org/en/reference/orm/).
10
+
11
+ ## Why?
12
+
13
+ Different CRDTs have different APIs. We want to make it as easy as possible to use them in the same way:\
14
+ **You modify a plain old TypeScript object and that updates the CRDT.**\
15
+ Vice versa, the CRDT is modified and that is reflected in your TS object.\
16
+ We offer this for **React, Vue, and Svelte**.
17
+
18
+ Note that we support discrete (**JSON**) CRDT and graph (**RDF**) CRDT ORMs.
19
+
20
+ - For graphs, you specify a schema using a SHEX shape and optionally a scope. This provides you with typing support.
21
+ - For discrete CRDTs, all you need is a document ID (NURI).
10
22
 
11
23
  ## Table of Contents
12
24
 
13
- - [@ng-org/orm](#ng-orgorm)
14
- - [Table of Contents](#table-of-contents)
15
- - [Installation](#installation)
16
- - [Quick Start](#quick-start)
17
- - [Defining Schemas](#defining-schemas)
18
- - [Framework Usage](#framework-usage)
19
- - [React](#react)
20
- - [Vue](#vue)
21
- - [Svelte](#svelte)
22
- - [Working with Data](#working-with-data)
23
- - [Adding Objects](#adding-objects)
24
- - [Modifying Objects](#modifying-objects)
25
- - [Deleting Objects](#deleting-objects)
26
- - [Working with Sets](#working-with-sets)
27
- - [Relationships](#relationships)
28
- - [API Reference](#api-reference)
29
- - [`useShape(shapeType)`](#useshapeshapetype)
30
- - [Shared State](#shared-state)
31
- - [License](#license)
25
+ - [Installation](#installation)
26
+ - [Start](#start)
27
+ - [Graph ORM: Defining Schemas](#graph-orm-defining-schemas)
28
+ - [Frontend Framework Usage](#frontend-framework-usage)
29
+ - [Working with Data](#working-with-data)
30
+ - [Creating a Document](#creating-a-document)
31
+ - [Using and Modifying ORM Objects](#using-and-modifying-orm-objects)
32
+ - [Graph ORM: Relationships](#graph-orm-relationships)
32
33
 
33
34
  ---
34
35
 
35
36
  ## Installation
36
37
 
37
38
  ```bash
38
- pnpm add @ng-org/orm @ng-org/web @ng-org/alien-deepsignals
39
+ pnpm add @ng-org/orm @ng-org/web
39
40
  ```
40
41
 
41
- For schema code generation, also install:
42
+ For schema generation, also install:
42
43
 
43
44
  ```bash
44
45
  pnpm add -D @ng-org/shex-orm
@@ -46,7 +47,9 @@ pnpm add -D @ng-org/shex-orm
46
47
 
47
48
  ---
48
49
 
49
- ## Quick Start
50
+ ## Start
51
+
52
+ You are strongly advised to look at the example apps for [discrete JSON documents](https://git.nextgraph.org/NextGraph/expense-tracker-discrete) and [typed graph documents](https://git.nextgraph.org/NextGraph/expense-tracker-graph).
50
53
 
51
54
  Before using the ORM, initialize NextGraph in your app entry point:
52
55
 
@@ -56,6 +59,7 @@ import { initNg } from "@ng-org/orm";
56
59
 
57
60
  await init(
58
61
  async (event) => {
62
+ // The ORM needs to have access to ng, the interface to the engine running in WASM.
59
63
  initNg(ng, event.session);
60
64
  },
61
65
  true,
@@ -63,27 +67,25 @@ await init(
63
67
  );
64
68
  ```
65
69
 
66
- Then use `useShape()` in your components:
70
+ Then use `useShape()` for graphs, or `useDiscrete()` for discrete documents.
67
71
 
68
- ```typescript
69
- import { useShape } from "@ng-org/orm/react"; // or /vue, /svelte
70
- import { DogShapeType } from "./shapes/orm/dogShape.shapeTypes";
72
+ In some cases, you may want to use advanced features managing subscriptions with the engine.
73
+ With an OrmSubscription, you can manage things like transactions manually.
74
+ This is useful for example when you want to manage a state across components.
75
+ See [`OrmSubscription.getOrCreate(ShapeType, scope)`](#getorcreate-1) for graphs
76
+ and [`DiscreteOrmSubscription.getOrCreate(documentId)`](#getorcreate) for discrete documents.
71
77
 
72
- const dogs = useShape(DogShapeType);
78
+ Internally, the OrmSubscription keeps a signalObject, a proxied, reactive object. When modifications are made, this makes the frontend components rerender and sends the update to the engine to be persisted.
73
79
 
74
- // Iterate, modify, add changes auto-sync everywhere
75
- for (const dog of dogs) {
76
- console.log(dog.name);
77
- }
78
- ```
80
+ In all cases, you have to create a document first with `ng.doc_create()`.
79
81
 
80
- ---
81
-
82
- ## Defining Schemas
82
+ ## Graph ORM: Defining Schemas
83
83
 
84
84
  Define your data model using [SHEX (Shape Expressions)](https://shex.io/):
85
+ See [@ng-org/shex-orm](../shex-orm/README.md) for details.
85
86
 
86
87
  **`shapes/shex/dogShape.shex`**:
88
+
87
89
  ```shex
88
90
  PREFIX ex: <http://example.org/>
89
91
  PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
@@ -99,237 +101,156 @@ ex:Dog {
99
101
  Generate TypeScript types. Add the following to your `package.json` scripts and run `build:orm`:
100
102
 
101
103
  ```json
102
- "build:orm": "rdf-orm build --input ./src/shapes/shex --output ./src/shapes/orm"
104
+ "build:orm": "rdf-orm build --input ./src/shapes/shex --output ./src/shapes/orm"
103
105
  ```
104
106
 
105
- This creates:
106
- - `dogShape.typings.ts` — TypeScript interfaces
107
- - `dogShape.shapeTypes.ts` Shape type objects for `useShape()`
108
- - `dogShape.schema.ts` — Internal schema metadata
109
-
110
- See [@ng-org/shex-orm](../shex-orm/README.md) for full documentation.
111
-
112
- ---
113
-
114
- ## Framework Usage
115
-
116
- ### React
117
-
118
- ```tsx
119
- import { useShape } from "@ng-org/orm/react";
120
- import { DogShapeType } from "./shapes/orm/dogShape.shapeTypes";
121
- import type { Dog } from "./shapes/orm/dogShape.typings";
122
-
123
- export function DogList() {
124
- const dogs = useShape(DogShapeType); // DeepSignalSet<Dog>
125
-
126
- return (
127
- <ul>
128
- {[...dogs].map(dog => (
129
- <li key={dog["@id"]}>
130
- {/* Direct mutation triggers re-render */}
131
- <input
132
- value={dog.name}
133
- onChange={e => dog.name = e.target.value}
134
- />
135
- </li>
136
- ))}
137
- </ul>
138
- );
139
- }
140
- ```
141
-
142
- > **Note**: No `setState` needed — just mutate the object directly.
143
-
144
- ### Vue
145
-
146
- **Parent component** (`DogList.vue`):
147
- ```vue
148
- <script setup lang="ts">
149
- import { useShape } from "@ng-org/orm/vue";
150
- import { DogShapeType } from "./shapes/orm/dogShape.shapeTypes";
151
- import DogCard from "./DogCard.vue";
152
-
153
- const dogs = useShape(DogShapeType); // DeepSignalSet<Dog>
154
- </script>
155
-
156
- <template>
157
- <DogCard
158
- v-for="dog in dogs"
159
- :key="dog['@id']"
160
- :dog="dog"
161
- />
162
- </template>
163
- ```
164
-
165
- **Child component** (`DogCard.vue`):
166
- ```vue
167
- <script setup lang="ts">
168
- import { useDeepSignal } from "@ng-org/alien-deepsignals/vue";
169
- import type { Dog } from "./shapes/orm/dogShape.typings";
170
-
171
- const props = defineProps<{ dog: Dog }>();
172
-
173
- // Required for reactivity in child components!
174
- const dog = useDeepSignal(props.dog);
175
- </script>
176
-
177
- <template>
178
- <div>
179
- <input v-model="dog.name" />
180
- </div>
181
- </template>
182
- ```
183
-
184
- > **Important**: In Vue child components, wrap props with `useDeepSignal()` to enable reactivity.
185
-
186
- ### Svelte
187
-
188
- ```svelte
189
- <script lang="ts">
190
- import { useShape } from "@ng-org/orm/svelte";
191
- import { DogShapeType } from "./shapes/orm/dogShape.shapeTypes";
192
-
193
- const dogs = useShape(DogShapeType); // Reactive store
194
- </script>
107
+ ## Frontend Framework Usage
108
+
109
+ The SDK offers hooks for discrete and graph-based CRDTs for Svelte, Vue and React:
110
+
111
+ - discrete CRDTs for
112
+ - Svelte 5: [useDiscrete](#svelteusediscrete)
113
+ - Svelte 3/4: [useDiscrete](#svelte4usediscrete)
114
+ - Vue: [useDiscrete](#vueusediscrete)
115
+ - React: [useDiscrete](#reactusediscrete)
116
+ - graph CRDTs for:
117
+ - Svelte 5: [useShape](#svelteuseshape)
118
+ - Svelte 3/4: [useShape](#svelte4useshape)
119
+ - Vue: [useShape](#vueuseshape)
120
+ - React: [useShape](#reactuseshape)
121
+
122
+ All of them have the same logic. They create a 2-way binding to the engine.
123
+ You can modify the returned object like any other JSON object. Changes are immediately
124
+ reflected in the CRDT and the components rerender.
125
+ When the component unmounts, the subscription is closed.
126
+
127
+ ```ts
128
+ // Queries the graphs with NURI did:ng:o:g1 and did:ng:o:g2 and with subject s1 or s2.
129
+ const expenses: DeepSignal<Set<Expense>> = useShape(ExpenseShapeType, {
130
+ graphs: ["did:ng:o:g1", "did:ng:o:g2"],
131
+ subjects: ["<s1 IRI>", "<s2 IRI>"],
132
+ });
195
133
 
196
- <ul>
197
- {#each [...$dogs] as dog (dog['@id'])}
198
- <li>
199
- <input bind:value={dog.name} />
200
- </li>
201
- {/each}
202
- </ul>
134
+ // Use expenses in your component
135
+ // and modify them to trigger a rerender and persist them.
136
+ // ...
203
137
  ```
204
138
 
205
- > **Note**: Access the store value with `$dogs`. Standard Svelte binding works.
206
-
207
139
  ---
208
140
 
209
141
  ## Working with Data
210
142
 
211
- ### Adding Objects
143
+ The ORM is designed to make working with data as normal as possible.
144
+ You get an object as you are used to it and when you change properties,
145
+ they are automatically persisted and synced with other devices. Conversely,
146
+ modifications arrive at the ORM objects immediately and your components rerender.
212
147
 
213
- To add a new object, you need a document IRI (`@graph`). Create a document first:
148
+ ### Creating a Document
214
149
 
215
- ```typescript
216
- import { sessionPromise } from "./utils/ngSession";
217
-
218
- const session = await sessionPromise;
150
+ First, you need a document to store and get your data.
151
+ With the document NURI, you can then create ORM objects.
219
152
 
153
+ ```ts
220
154
  // Create a new NextGraph document
221
- const docIri = await session.ng.doc_create(
222
- session.session_id,
223
- "Graph",
224
- "data:graph",
155
+ const docNuri = await ng.doc_create(
156
+ session_id,
157
+ "Graph", // Or "YMap" or "Automerge", for discrete
158
+ "data:graph", // Or "data:json" : "data:map" for Automerge or YJs
225
159
  "store",
226
160
  undefined
227
161
  );
228
162
 
229
- // Add to the reactive set
230
- dogs.add({
231
- "@graph": docIri, // Required: document IRI
232
- "@type": "http://example.org/Dog", // Required: RDF type
233
- "@id": "", // Empty = auto-generate subject IRI
234
- name: "Buddy",
235
- age: 3,
236
- toys: new Set(["ball", "rope"]),
237
- });
163
+ // Add class to RDF part of the document so we can find it again.
164
+ await ng.sparql_update(
165
+ session_id,
166
+ `INSERT DATA { GRAPH <${documentId}> {<${documentId}> a <${APPLICATION_CLASS_IRI}> } }`,
167
+ documentId
168
+ );
238
169
  ```
239
170
 
240
- > **Note**: For nested sub-objects, `@graph` is optional the parent's graph IRI is used.
241
- >
242
- > **Note**: If you want to use the ORM signal object in a non-component context, you can use `createSignalObjectForShape` function as well.
243
-
244
- ### Modifying Objects
171
+ To find your document, you can make a sparql query as well:
245
172
 
246
- Simply assign new values:
247
-
248
- ```typescript
249
- dog.name = "Max";
250
- dog.age = 4;
173
+ ```ts
174
+ const ret = await ng.sparql_query(
175
+ session_id,
176
+ `SELECT ?storeId WHERE { GRAPH ?storeId { ?s a <${APPLICATION_CLASS_IRI}> } }`,
177
+ undefined,
178
+ undefined
179
+ );
180
+ let documentId = ret?.results.bindings?.[0]?.storeId?.value;
251
181
  ```
252
182
 
253
- Changes are:
254
- - Immediately reflected in all components using the same shape
255
- - Automatically persisted to NextGraph storage
256
- - Synced to other devices in real-time
257
-
258
- ### Deleting Objects
183
+ ### Using and Modifying ORM Objects
259
184
 
260
- ```typescript
261
- dogs.delete(dog);
262
- ```
185
+ There are multiple ways to get and modify data:
263
186
 
264
- ### Working with Sets
265
-
266
- Properties with SHEX cardinality `*` or `+` become reactive Sets:
187
+ - Get and modify the data returned by a `useShape()` or `useDiscrete()` hook inside a component.
188
+ - Get and modify the signalObject of the subscription returned by `Orm(Discrete)Subscription.getOrCreate()`.
189
+ - For graph ORMs: Call [`insertObject()`](#insertobject) or [`getObjects`](#getobjects) (no 2-way binding).
267
190
 
268
191
  ```typescript
269
- // Add items
270
- dog.toys.add("frisbee");
192
+ const dogSubscription = OrmSubscription.getOrCreate(DogShape, {
193
+ graphs: [docNuri],
194
+ });
195
+ await dogSubscription.readyPromise;
271
196
 
272
- // Remove items
273
- dog.toys.delete("ball");
197
+ // If we used OrmDiscreteSubscription, the signalObject type would be array or object.
198
+ const dogSet: DeepSignal<Set<Dog>> = dogSubscription.signalObject;
274
199
 
275
- // Check membership
276
- if (dog.toys.has("rope")) { ... }
200
+ dogs.add({
201
+ // Required: The document NURI. May be set to `""` for nested objects (will be inherited from parent object then).
202
+ "@graph": docNuri,
203
+ "@type": "did:ng:x:Dog", // Required: RDF type
204
+ "@id": "", // Empty string = auto-generate subject IRI
205
+ name: "Mr Puppy",
206
+ age: 2,
207
+ toys: new Set(["ball", "rope"]),
208
+ });
277
209
 
278
- // Iterate
279
- for (const toy of dog.toys) {
280
- console.log(toy);
281
- }
210
+ // When you know that only one element is in the set, you can call `.first()` to get it.
211
+ const aDog = dogs.first();
212
+ aDog.age += 1;
213
+ aDog.toy.add("bone");
282
214
 
283
- // Get size
284
- console.log(dog.toys.size);
215
+ // Utility to find objects in sets:
216
+ const sameDog = dogs.getBy(aDog["@graph"], aDog["@id"]);
217
+ // sameSog === aDog.
285
218
 
286
- // NOTE: For ES2025 environment, set iterator objects are directly attached:
287
- dogs.forEach((dog) => {
288
- console.log(dog.toys.size);
289
- });
219
+ dogs.delete(aDog);
290
220
  ```
291
221
 
292
- ### Relationships
222
+ Note that the graph CRDT supports sets only, the discrete CRDTs arrays only.
293
223
 
294
- Link objects by storing the target's `@id` IRI:
224
+ #### Graph ORM: Relationships
225
+
226
+ To reference external objects, you can use their `@id`.
295
227
 
296
228
  ```typescript
297
- // In your SHEX schema:
298
- // ex:owner IRI ;
229
+ casey.friends.add(jackNuri);
299
230
 
300
- // Link to another object
301
- dog.owner = person["@id"];
231
+ // When the child object is a nested object that you do not have in memory,
232
+ // you can establish the link by adding an object that contains the `@id` property only.
233
+ shoppingExpense.category.add({ "@id": "<Subject IRI of expense category>" });
234
+ // Link objects by storing the target's `@id` NURI/IRI:
302
235
 
236
+ dog.owner = jackNuri;
303
237
  // Resolve the relationship
304
- const owner = people.find(p => p["@id"] === dog.owner);
305
- ```
306
-
307
- ---
308
-
309
- ## API Reference
310
-
311
- ### `useShape(shapeType)`
312
-
313
- Returns a `DeepSignalSet<T>` containing all objects of the given shape type.
314
-
315
- ```typescript
316
- const dogs = useShape(DogShapeType);
238
+ const jack = people.find((p) => p["@id"] === dog.owner);
317
239
  ```
318
240
 
319
- **DeepSignalSet methods:**
320
- - `add(obj)` — Add a new object
321
- - `delete(obj)` — Remove an object
322
- - `has(obj)` — Check if object exists
323
- - `size` — Number of objects
324
- - `getBy(graphIri, subjectIri)` — Find object by IRIs
325
- - `[Symbol.iterator]` — Iterate with `for...of` or spread `[...set]`
326
- - ... and all symbol iterator helper methods (like `.map`, `.find`, ...), if you are in an ES2025+ environment.
241
+ Note that when you delete a nested object from a parent, _only the linkage_ to it is removed. The nested object itself (its quads) are not deleted.
327
242
 
328
- ### Shared State
243
+ ---
329
244
 
330
- When `useShape()` is called with the same shape type and scope in multiple components, they share the exact same reactive data. Changes in one component instantly appear in all others.
245
+ ## About NextGraph
331
246
 
332
- ---
247
+ > **NextGraph** brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs.
248
+ >
249
+ > This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with **end-to-end encryption**, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy.
250
+ >
251
+ > Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers.
252
+ >
253
+ > More info: [https://nextgraph.org](https://nextgraph.org)
333
254
 
334
255
  ## License
335
256
 
@@ -337,7 +258,7 @@ Licensed under either of
337
258
 
338
259
  - Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0)
339
260
  - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
340
-
261
+
341
262
  at your option.
342
263
 
343
264
  `SPDX-License-Identifier: Apache-2.0 OR MIT`
@@ -1,9 +1,11 @@
1
+ /** @ignore */
1
2
  export type Patch = {
2
3
  /** Property path (array indices, object keys, synthetic Set entry ids) from the root to the mutated location. */
3
4
  path: string;
4
5
  valType?: string & {};
5
6
  value?: unknown;
6
- } & (SetAddPatch | SetRemovePatch | ObjectAddPatch | RemovePatch | LiteralAddPatch);
7
+ } & (SetAddPatch | SetRemovePatch | RemovePatch | LiteralAddPatch);
8
+ /** @ignore */
7
9
  export interface SetAddPatch {
8
10
  /** Mutation kind applied at the resolved `path`. */
9
11
  op: "add";
@@ -15,6 +17,7 @@ export interface SetAddPatch {
15
17
  */
16
18
  value: number | string | boolean | (number | string | boolean)[];
17
19
  }
20
+ /** @ignore */
18
21
  export interface SetRemovePatch {
19
22
  /** Mutation kind applied at the resolved `path`. */
20
23
  op: "remove";
@@ -24,83 +27,50 @@ export interface SetRemovePatch {
24
27
  * - A single primitive
25
28
  * - An array of primitives
26
29
  */
27
- value: number | string | boolean | (number | string | boolean)[];
28
- }
29
- export interface ObjectAddPatch {
30
- /** Mutation kind applied at the resolved `path`. */
31
- op: "add";
32
- valType: "object";
30
+ value: number | string | boolean | object | (number | string | boolean | object)[];
33
31
  }
32
+ /** @ignore */
34
33
  export interface RemovePatch {
35
34
  /** Mutation kind applied at the resolved `path`. */
36
35
  op: "remove";
37
36
  }
37
+ /** @ignore */
38
38
  export interface LiteralAddPatch {
39
39
  /** Mutation kind applied at the resolved `path`. */
40
40
  op: "add";
41
41
  /** The literal value to be added at the resolved `path` */
42
- value: string | number | boolean;
42
+ value: string | number | boolean | object;
43
43
  }
44
44
  /**
45
+ * @ignore
46
+ *
45
47
  * Apply a diff to an object.
46
48
  *
47
49
  * The syntax is inspired by RFC 6902 but it is not compatible.
48
50
  *
49
51
  * It supports Sets for multi-valued properties:
50
52
  * - Primitive values are added as Sets (Set<string | number | boolean>)
51
- * - Multi-valued objects are stored in Sets, accessed by their @id property
52
- * - Single objects are plain objects with an @id property
53
+ * - Multi-valued objects are stored in Sets, accessed by their `@id` property
54
+ * - Single objects are plain objects with an `@id` property
53
55
  *
54
56
  * Path traversal:
55
- * - When traversing through a Set, the path segment is treated as an @id to find the object
57
+ * - When traversing through a Set, the path segment is treated as an `@id` to find the object
56
58
  * - When traversing through a plain object, the path segment is a property name
57
59
  *
58
- * @example operations
59
- * ```jsonc
60
- * // === SINGLE OBJECT ===
61
- * // Creating a single object (has @id at same level)
62
- * { "op": "add", "path": "/urn:example:person1/address", "valType": "object" }
63
- * { "op": "add", "path": "/urn:example:person1/address/@id", "value": "urn:test:address1" }
64
- * // Adding primitives to single object
65
- * { "op": "add", "path": "/urn:example:person1/address/street", "value": "1st street" }
66
- * { "op": "add", "path": "/urn:example:person1/address/country", "value": "Greece" }
67
- * // Remove a primitive from object
68
- * { "op": "remove", "path": "/urn:example:person1/address/street" }
69
- * // Remove the entire object
70
- * { "op": "remove", "path": "/urn:example:person1/address" }
71
- *
72
- * // === MULTI-VALUED OBJECTS (Set) ===
73
- * // Creating a multi-object container (NO @id at this level -> creates Set)
74
- * { "op": "add", "path": "/urn:example:person1/children", "valType": "object" }
75
- * // Adding an object to the Set (path includes object's @id)
76
- * { "op": "add", "path": "/urn:example:person1/children/urn:example:child1", "valType": "object" }
77
- * { "op": "add", "path": "/urn:example:person1/children/urn:example:child1/@id", "value": "urn:example:child1" }
78
- * // Adding properties to object in Set
79
- * { "op": "add", "path": "/urn:example:person1/children/urn:example:child1/name", "value": "Alice" }
80
- * // Remove an object from Set
81
- * { "op": "remove", "path": "/urn:example:person1/children/urn:example:child1" }
82
- * // Remove all objects (the Set itself)
83
- * { "op": "remove", "path": "/urn:example:person1/children" }
84
- *
85
- * // === PRIMITIVE SETS ===
86
- * // Add primitive types to Sets
87
- * { "op": "add", "valType": "set", "path": "/urn:example:person1/tags", "value": [1,2,3] }
88
- * // Remove primitive types from a Set
89
- * { "op": "remove", "valType": "set", "path": "/urn:example:person1/tags", "value": [1,2] }
90
- * ```
91
- *
92
60
  * @param currentState The object before the patch
93
61
  * @param patches An array of patches to apply to the object.
94
62
  * @param ensurePathExists If true, create nested objects along the path if the path does not exist.
95
63
  *
96
- * @note When creating new objects, this function pre-scans upcoming patches to find @id and @graph
64
+ * Note: When creating new objects, this function pre-scans upcoming patches to find `@id` and `@graph`
97
65
  * values that will be assigned to the object. This prevents the signal library's propGenerator
98
66
  * from being triggered before these identity fields are set, which would cause it to generate
99
67
  * random IDs unnecessarily.
100
68
  */
101
- export declare function applyPatches(currentState: Record<string, any>, patches: Patch[], ensurePathExists?: boolean): void;
69
+ export declare function applyPatches(currentState: Record<string, any>, patches: Patch[], ormType: "set" | "discrete", ensurePathExists?: boolean): void;
102
70
  /**
103
- * See documentation for applyDiff
71
+ * @ignore
72
+ *
73
+ * See documentation for applyPatches
104
74
  */
105
- export declare function applyPatchesToDeepSignal(currentState: object, patch: Patch[]): void;
75
+ export declare function applyPatchesToDeepSignal(currentState: object, patch: Patch[], ormType: "set" | "discrete"): void;
106
76
  //# sourceMappingURL=applyPatches.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"applyPatches.d.ts","sourceRoot":"","sources":["../../src/connector/applyPatches.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,KAAK,GAAG;IAChB,iHAAiH;IACjH,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CACE,WAAW,GACX,cAAc,GACd,cAAc,GACd,WAAW,GACX,eAAe,CACpB,CAAC;AAEF,MAAM,WAAW,WAAW;IACxB,oDAAoD;IACpD,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,KAAK,CAAC;IACf;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CACpE;AAED,MAAM,WAAW,cAAc;IAC3B,oDAAoD;IACpD,EAAE,EAAE,QAAQ,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;IACf;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CACpE;AAED,MAAM,WAAW,cAAc;IAC3B,oDAAoD;IACpD,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,oDAAoD;IACpD,EAAE,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC5B,oDAAoD;IACpD,EAAE,EAAE,KAAK,CAAC;IACV,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CACpC;AAyCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,YAAY,CACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,OAAO,EAAE,KAAK,EAAE,EAChB,gBAAgB,GAAE,OAAe,QAgOpC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAI5E"}
1
+ {"version":3,"file":"applyPatches.d.ts","sourceRoot":"","sources":["../../src/connector/applyPatches.ts"],"names":[],"mappings":"AAYA,cAAc;AACd,MAAM,MAAM,KAAK,GAAG;IAChB,iHAAiH;IACjH,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CAAC,WAAW,GAAG,cAAc,GAAG,WAAW,GAAG,eAAe,CAAC,CAAC;AAEnE,cAAc;AACd,MAAM,WAAW,WAAW;IACxB,oDAAoD;IACpD,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,KAAK,CAAC;IACf;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CACpE;AAED,cAAc;AACd,MAAM,WAAW,cAAc;IAC3B,oDAAoD;IACpD,EAAE,EAAE,QAAQ,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;IACf;;;;OAIG;IACH,KAAK,EACC,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;CAChD;AAED,cAAc;AACd,MAAM,WAAW,WAAW;IACxB,oDAAoD;IACpD,EAAE,EAAE,QAAQ,CAAC;CAChB;AAED,cAAc;AACd,MAAM,WAAW,eAAe;IAC5B,oDAAoD;IACpD,EAAE,EAAE,KAAK,CAAC;IACV,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CAC7C;AAyCD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,OAAO,EAAE,KAAK,EAAE,EAChB,OAAO,EAAE,KAAK,GAAG,UAAU,EAC3B,gBAAgB,GAAE,OAAe,QA6PpC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACpC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,KAAK,EAAE,EACd,OAAO,EAAE,KAAK,GAAG,UAAU,QAU9B"}