@_linked/core 2.14.1 → 2.14.2-next.20260709131204

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.14.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#164](https://github.com/linked-cm/core/pull/164) [`17bfb35`](https://github.com/linked-cm/core/commit/17bfb35049aff5e3482ea54cbcc074639476adbe) Thanks [@flyon](https://github.com/flyon)! - docs: document **owned properties** in the README — a new "Owned properties (`contains` / `dependent`)" section under Shapes explaining exclusive-ownership object properties (`contains: true`) and the automatic cascade cleanup on update-replace, set-remove, and parent-delete, and how the property-level `contains` flag differs from the shape-level `dependent` flag. No code change.
8
+
3
9
  ## 2.14.1
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -236,6 +236,48 @@ export class Person extends Shape {
236
236
  }
237
237
  ```
238
238
 
239
+ ### Owned properties (`contains` / `dependent`)
240
+
241
+ By default an object property is a plain *reference*: the two nodes exist independently, and
242
+ removing the link leaves the referenced node untouched. Two optional flags let you model
243
+ **composition** (ownership) instead, so the framework cleans owned nodes up automatically.
244
+
245
+ **`contains: true` on an object property** — the edge asserts *exclusive ownership* of the
246
+ value. Whenever that edge goes away, the owned node is deleted with it:
247
+
248
+ - `parent.delete()` deletes the owned child (and its owned sub-tree).
249
+ - `update({ownedProp: newValue})` **replaces** the owned node — the old one is deleted, not
250
+ orphaned.
251
+ - `update({ownedProp: {remove: [x]}})` deletes `x` itself, not just the link.
252
+
253
+ ```typescript
254
+ @linkedShape
255
+ export class Person extends Shape {
256
+ static targetClass = ex.Person;
257
+
258
+ // Person exclusively owns its avatar image. Replacing or clearing `avatar`,
259
+ // or deleting the Person, deletes the old ImageObject too.
260
+ @objectProperty({path: ex.avatar, shape: ImageObject, maxCount: 1, contains: true})
261
+ declare avatar: ImageObject;
262
+ }
263
+ ```
264
+
265
+ **`dependent: true` on a shape** — marks the shape's *instances* as having no independent
266
+ existence, so they are cascade-deleted when reached through a `contains` edge from a parent
267
+ being deleted. Use it for structural nodes that are only ever owned (e.g. list cells, path
268
+ nodes). It is **not** required for the replace/remove cleanup above — a `contains` edge alone
269
+ is sufficient for the immediately-owned node; `dependent` extends the cascade to owned
270
+ *descendants* several hops deep.
271
+
272
+ ```typescript
273
+ @linkedShape({dependent: true})
274
+ export class ListCell extends Shape { /* ... */ }
275
+ ```
276
+
277
+ > Rule of thumb: put `contains` on the **property** that owns the value; put `dependent` on the
278
+ > **shape** whose instances never stand alone. They are separate mechanisms — `contains` decides
279
+ > *what to follow*, `dependent` decides *what may be deleted when reached*.
280
+
239
281
  ## Queries: Create, Select, Update, Delete
240
282
 
241
283
  Queries are expressed with the same Shape classes and compile to a query object that a store executes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_linked/core",
3
- "version": "2.14.1",
3
+ "version": "2.14.2-next.20260709131204",
4
4
  "license": "MIT",
5
5
  "linkedPackage": true,
6
6
  "type": "module",