@solidev/data 1.0.1 → 1.1.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/AGENTS.md CHANGED
@@ -371,6 +371,52 @@ Notes worth knowing:
371
371
  **Do not try to bind `[save]`.** It is declared as a plain class property, not an
372
372
  `input()`, so it is not template-bindable. Control saving via `mode`.
373
373
 
374
+ ### 7.1 Long text — `<data-richedit>` and `<data-mdedit>`
375
+
376
+ **They are not dispedit editors.** `dispedit` lives in the primary entry point and
377
+ cannot import a secondary one, so use these components directly. For the
378
+ read-only half, point a dispedit at the rendered `…_html` column with
379
+ `[viewer]="'html'"` — that renders trusted HTML and covers markdown too, since a
380
+ markdown field is stored with an `…_html` twin. It does **not** sanitize: use it
381
+ only on HTML your own editor produced.
382
+
383
+ Two editors live in their own entry points, so they are only pulled in if imported:
384
+
385
+ ```html
386
+ <!-- HTML, @solidev/data/richedit -->
387
+ <data-richedit [model]="thing" field="description">Description</data-richedit>
388
+
389
+ <!-- markdown source, @solidev/data/mdedit -->
390
+ <data-mdedit [model]="thing" field="notes" toolbar="light">Notes</data-mdedit>
391
+ ```
392
+
393
+ Same inputs on both (`model`, `field`, `htmlField`, `mode`, `edit`, `editable`,
394
+ `hideLabel`, `hideButton`, `fc`, `form`, `toolbar`), one output (`changed`).
395
+
396
+ - **They show the value first.** In `dd` mode a click on the value or the label
397
+ reveals the editor, exactly like dispedit; `[editable]="false"` forbids it.
398
+ `inline` and `form` show the editor straight away.
399
+ - **`field` names a pair.** Given `field="description"` they edit
400
+ `description_src` and display `description_html` when the model declares them,
401
+ and fall back to `description` for both when it does not. `[htmlField]`
402
+ overrides the display half.
403
+
404
+ - **They do not auto-save.** Unlike dispedit, the value reaches the API only when
405
+ the built-in save button runs `save()`, and only in `mode="dd"`. In `inline` and
406
+ `form` the model is updated in memory and nothing is sent.
407
+ - **`[fc]` short-circuits everything.** Supply your own control and there is no
408
+ field manager lookup, no seeding from the model, and **no `changed` emissions**.
409
+ - **No extra install.** `prosemirror-*` and `@codemirror/*` are ordinary peer
410
+ dependencies, so npm brings them in with the library. Neither reaches the
411
+ application bundle unless its entry point is imported.
412
+ - **Rendering a `…_html` column elsewhere** needs `SafeHtmlPipe` from
413
+ `@solidev/data`: `<div [innerHTML]="thing.notes_html | safeHtml"></div>`.
414
+ Angular's sanitizer drops the inline styles the editor writes, so a plain
415
+ `[innerHTML]` renders alignment and colours away. Server-produced HTML only.
416
+ - **Testing needs `installEditorDomShims()`** from `@solidev/data`, called in
417
+ `beforeEach` — jsdom has no layout engine and both editors measure the document.
418
+ Then `await fixture.whenStable()`, since both mount in `afterNextRender`.
419
+
374
420
  ---
375
421
 
376
422
  ## 8. Bootstrap wiring
package/README.md CHANGED
@@ -1,36 +1,37 @@
1
1
  # @solidev/data
2
2
 
3
- A **Django-REST-Framework-style data layer for Angular**. Declare a model once and get
4
- HTTP access, querysets, filtering, sorting, pagination, forms, validation and
5
- display/edit widgets — all driven by that single declaration.
3
+ A **Django-REST-Framework-style data layer for Angular**. Declare a model once and get HTTP access, querysets,
4
+ filtering, sorting, pagination, forms, validation and display/edit widgets — all driven by that single declaration.
6
5
 
7
6
  ```ts
8
7
  export class ProductBase extends DataModel {
9
- static override readonly __name: string = 'ProductBase';
8
+ static override readonly __name: string = "ProductBase";
10
9
 
11
- @charField({ description: 'Name', maxLength: 200 })
10
+ @charField({ description: "Name", maxLength: 200 })
12
11
  public name!: string;
13
12
 
14
- @charField({ description: 'Status', choices: [
15
- { value: 'draft', desc: 'Draft' },
16
- { value: 'published', desc: 'Published' },
17
- ]})
13
+ @charField({
14
+ description: "Status",
15
+ choices: [
16
+ { value: "draft", desc: "Draft" },
17
+ { value: "published", desc: "Published" },
18
+ ],
19
+ })
18
20
  public status!: string;
19
21
 
20
- @foreignKeyField({ description: 'Category', related: 'Category', priority: -1 })
22
+ @foreignKeyField({ description: "Category", related: "Category", priority: -1 })
21
23
  public category!: number;
22
24
  }
23
25
  ```
24
26
 
25
27
  ```html
26
- <data-dispedit [model]="product" field="name" mode="dd" [editable]="true" />
28
+ <data-dispedit [model]="product" field="name" mode="dd" [editable]="true" />
27
29
  <data-dispedit [model]="product" field="status" mode="dd" [editable]="true" />
28
- <data-dispedit [model]="product" field="category" mode="dd" [editable]="true"
29
- [collection]="categories" />
30
+ <data-dispedit [model]="product" field="category" mode="dd" [editable]="true" [collection]="categories" />
30
31
  ```
31
32
 
32
- That is the whole idea: `status` renders as a `<select>` and `category` as an FK
33
- dropdown **because the field metadata says so**. You declare the model; the UI follows.
33
+ That is the whole idea: `status` renders as a `<select>` and `category` as an FK dropdown **because the field metadata
34
+ says so**. You declare the model; the UI follows.
34
35
 
35
36
  ## Install
36
37
 
@@ -40,57 +41,52 @@ npm install @solidev/data
40
41
 
41
42
  ```ts
42
43
  bootstrapApplication(AppComponent, {
43
- providers: [
44
- { provide: DATA_API_URL, useValue: 'https://api.example.com/v1' },
45
- provideHttpClient(),
46
- ],
44
+ providers: [{ provide: DATA_API_URL, useValue: "https://api.example.com/v1" }, provideHttpClient()],
47
45
  });
48
46
  ```
49
47
 
50
48
  ## What's in the box
51
49
 
52
- | Module | What it gives you |
53
- |---|---|
54
- | **data** | `DataModel` + field decorators, `Collection<T>`, `Queryset<T>`, `DataBackend` (with SSR `TransferState` support) |
55
- | **modellist** | `ModelListService` — field selection, filters, sorter, paginator, and the components to render them |
56
- | **dispedit** | `<data-dispedit>` and friends — metadata-driven display/edit, FK/M2M pickers, flags, safe-delete |
57
- | **auth** | JWT service + interceptor with automatic refresh and replay |
58
- | **messages, routing, updates, uploader, richedit** | supporting pieces |
50
+ | Module | What it gives you |
51
+ | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
52
+ | **data** | `DataModel` + field decorators, `Collection<T>`, `Queryset<T>`, `DataBackend` (with SSR `TransferState` support) |
53
+ | **modellist** | `ModelListService` — field selection, filters, sorter, paginator, and the components to render them |
54
+ | **dispedit** | `<data-dispedit>` and friends — metadata-driven display/edit, FK/M2M pickers, flags, safe-delete |
55
+ | **auth** | JWT service + interceptor with automatic refresh and replay |
56
+ | **messages, routing, updates, uploader, richedit** | supporting pieces |
59
57
 
60
58
  ## Documentation
61
59
 
62
- - **Guides** — see the `docs/` directory in the repository, also published in the
63
- generated documentation under **Guides**.
64
- - **API reference** — generated with [compodoc](https://compodoc.app):
65
- `npm run mkdocs:serve`.
66
- - **Worked example** `projects/data/src/examples/catalog/`, a small catalog domain
67
- (tree categories, m2m tags, geolocated stores, flags) that is **test-covered**, so it
68
- cannot drift from the library.
60
+ - **Guides** — see the `docs/` directory in the repository, also published in the generated documentation under
61
+ **Guides**.
62
+ - **API reference** — generated with [compodoc](https://compodoc.app): `npm run mkdocs:serve`.
63
+ - **Worked example** — `projects/data/src/examples/catalog/`, a small catalog domain (tree categories, m2m tags,
64
+ geolocated stores, flags) that is **test-covered**, so it cannot drift from the library.
69
65
 
70
66
  ### Using this library with an AI agent
71
67
 
72
- This package ships **[`AGENTS.md`](./AGENTS.md)** — a rules file covering the model
73
- conventions and the runtime contracts that fail silently when broken. It is available
74
- in consuming projects at `node_modules/@solidev/data/AGENTS.md`.
68
+ This package ships **[`AGENTS.md`](./AGENTS.md)** — a rules file covering the model conventions and the runtime
69
+ contracts that fail silently when broken. It is available in consuming projects at
70
+ `node_modules/@solidev/data/AGENTS.md`.
75
71
 
76
72
  Point your agent at it from your own `AGENTS.md` / `CLAUDE.md`:
77
73
 
78
74
  ```markdown
79
- This project uses `@solidev/data`. Before writing or changing any model, collection,
80
- list component, or `dispedit` usage, read `node_modules/@solidev/data/AGENTS.md`
81
- and follow it.
75
+ This project uses `@solidev/data`. Before writing or changing any model, collection, list component, or `dispedit`
76
+ usage, read `node_modules/@solidev/data/AGENTS.md` and follow it.
82
77
  ```
83
78
 
84
79
  ## Start here
85
80
 
86
- Whatever else you skip, read the **Relations** guide and the **Traps** guide. The
87
- FK ⇄ details pairing is a runtime contract enforced by string concatenation, and most
88
- of the ways to misuse this library fail **silently**.
81
+ Whatever else you skip, read the **Relations** guide and the **Traps** guide. The FK ⇄ details pairing is a runtime
82
+ contract enforced by string concatenation, and most of the ways to misuse this library fail **silently**.
89
83
 
90
84
  ## Requirements
91
85
 
92
- Angular 22+. Peer dependencies: `@angular/common`, `@angular/core`, and depending on
93
- which parts you use — `@ng-bootstrap/ng-bootstrap`, `jwt-decode`, `ngx-editor`.
86
+ Angular 22+. Peer dependencies: `@angular/common`, `@angular/core`, `@ng-bootstrap/ng-bootstrap` and `jwt-decode`, plus
87
+ the engines behind the two editor entry points `prosemirror-*` for `@solidev/data/richedit` and `@codemirror/*` for
88
+ `@solidev/data/mdedit`. npm 7+ installs all of them with the package; the editors only reach your bundle if you import
89
+ their entry point.
94
90
 
95
91
  ## Licence
96
92