@adobe/data 0.9.70 → 0.9.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/package.json +1 -1
- package/references/data-lit/package.json +1 -1
- package/references/data-lit/src/elements/database-element.ts +24 -21
- package/references/data-lit/src/elements/database-element.type-test.ts +21 -0
- package/references/data-lit-tictactoe/package.json +1 -1
- package/references/data-react/package.json +1 -1
- package/references/data-react-hello/package.json +1 -1
- package/references/data-react-pixie/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
2
|
|
|
3
3
|
import { LitElement } from 'lit';
|
|
4
|
-
import { property } from 'lit/decorators.js';
|
|
5
4
|
import { iterateSelfAndAncestors } from '../functions/index.js';
|
|
6
5
|
import { Database } from '@adobe/data/ecs';
|
|
7
6
|
import { UIService } from '@adobe/data/service';
|
|
@@ -9,22 +8,23 @@ import { attachDecorator, withHooks } from '../index.js';
|
|
|
9
8
|
|
|
10
9
|
export abstract class DatabaseElement<P extends Database.Plugin> extends LitElement {
|
|
11
10
|
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
* or created from `plugin` on connect. Bootstrap containers — those that own
|
|
15
|
-
* a controller or drive a streaming (async-generator) transaction — read
|
|
16
|
-
* this directly; pure widgets use the restricted `service` view below.
|
|
17
|
-
*/
|
|
18
|
-
@property({ type: Object, reflect: false })
|
|
19
|
-
database!: Database.Plugin.ToDatabase<P>;
|
|
11
|
+
/** Full database, hard-private — invisible to subclasses and external callers. */
|
|
12
|
+
#database!: Database.Plugin.ToDatabase<P>;
|
|
20
13
|
|
|
21
14
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
15
|
+
* The element's database surface.
|
|
16
|
+
* - SET to inject the full database (DI).
|
|
17
|
+
* - GET returns the UI-restricted view (every mutator rewritten to
|
|
18
|
+
* fire-and-forget `void`).
|
|
19
|
+
* Divergent get/set types are intentional: inject full, consume restricted.
|
|
25
20
|
*/
|
|
21
|
+
set service(db: Database.Plugin.ToDatabase<P>) {
|
|
22
|
+
const old = this.#database;
|
|
23
|
+
this.#database = db;
|
|
24
|
+
this.requestUpdate('service', old);
|
|
25
|
+
}
|
|
26
26
|
get service(): UIService.FromService<Database.Plugin.ToDatabase<P>> {
|
|
27
|
-
return UIService.restrict(this
|
|
27
|
+
return UIService.restrict(this.#database);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
constructor() {
|
|
@@ -35,19 +35,22 @@ export abstract class DatabaseElement<P extends Database.Plugin> extends LitElem
|
|
|
35
35
|
abstract get plugin(): P;
|
|
36
36
|
|
|
37
37
|
connectedCallback(): void {
|
|
38
|
-
if (!this
|
|
39
|
-
const ancestor = this.
|
|
40
|
-
this.
|
|
38
|
+
if (!this.#database) {
|
|
39
|
+
const ancestor = this.findAncestorService();
|
|
40
|
+
this.service = ancestor?.extend(this.plugin) ?? Database.create(this.plugin);
|
|
41
41
|
}
|
|
42
42
|
super.connectedCallback();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
protected
|
|
45
|
+
protected findAncestorService(): Database | void {
|
|
46
46
|
for (const element of iterateSelfAndAncestors(this)) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
// Read each ancestor's `service`. A DatabaseElement returns its full
|
|
48
|
+
// database here (UIService.restrict is identity at runtime); a foreign
|
|
49
|
+
// host (`<div .service=${db}>`) returns whatever was bound. Database.is
|
|
50
|
+
// keeps only a real database, skipping unconnected elements (undefined)
|
|
51
|
+
// and unrelated services (e.g. an ApplicationElement's MainService).
|
|
52
|
+
const { service } = element as { service?: unknown };
|
|
53
|
+
if (Database.is(service)) return service;
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -37,6 +37,27 @@ class _CountElement extends DatabaseElement<typeof plugin> {
|
|
|
37
37
|
type ServiceType = _CountElement["service"];
|
|
38
38
|
type RawDatabase = Database.Plugin.ToDatabase<typeof plugin>;
|
|
39
39
|
|
|
40
|
+
// 0. `service` is a read/write accessor: the getter returns the restricted view,
|
|
41
|
+
// while the setter accepts the full database (injection). The divergent
|
|
42
|
+
// get/set types are intentional (legal since TS 5.1).
|
|
43
|
+
const _injectFullDatabase = (el: _CountElement, db: RawDatabase): void => {
|
|
44
|
+
el.service = db;
|
|
45
|
+
};
|
|
46
|
+
// A side effect of the divergence: `el.service = el.service` is a type error,
|
|
47
|
+
// since the restricted getter type is not assignable to the full setter type.
|
|
48
|
+
const _rejectRestrictedAssignment = (el: _CountElement): void => {
|
|
49
|
+
// @ts-expect-error restricted view is not assignable back to the full database
|
|
50
|
+
el.service = el.service;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// 0a. The full database is fully encapsulated: there is no `database` member of
|
|
54
|
+
// any visibility on the instance type. `service` is the only surface.
|
|
55
|
+
const _noPublicDatabaseProperty = (el: _CountElement): void => {
|
|
56
|
+
// @ts-expect-error `database` no longer exists; the full db is hard-private
|
|
57
|
+
void el.database;
|
|
58
|
+
};
|
|
59
|
+
type _CheckNoDatabaseKey = Assert<Equal<Extract<keyof _CountElement, "database">, never>>;
|
|
60
|
+
|
|
40
61
|
// 1. The exposed service type is the UIService-restricted view of the database.
|
|
41
62
|
type _CheckRestricted = Assert<Equal<ServiceType, UIService.FromService<RawDatabase>>>;
|
|
42
63
|
|