@adobe/data 0.9.36 → 0.9.39
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 +91 -0
- package/dist/ecs/database/observe-select-deep.d.ts +23 -0
- package/dist/ecs/database/observe-select-deep.js +15 -0
- package/dist/ecs/database/observe-select-deep.js.map +1 -0
- package/dist/ecs/database/observe-select-deep.type-test.js +111 -0
- package/dist/ecs/database/observe-select-deep.type-test.js.map +1 -0
- package/dist/ecs/persistence-service/create-storage-persistence-service.js +4 -3
- package/dist/ecs/persistence-service/create-storage-persistence-service.js.map +1 -1
- package/dist/ecs/persistence-service/create-storage-persistence-service.test.js +52 -0
- package/dist/ecs/persistence-service/create-storage-persistence-service.test.js.map +1 -0
- package/dist/service/agentic-service/link.d.ts +15 -0
- package/dist/service/agentic-service/link.js +3 -0
- package/dist/service/agentic-service/link.js.map +1 -0
- package/dist/service/async-data-service/is-valid.d.ts +3 -1
- package/dist/service/async-data-service/is-valid.type-test.d.ts +1 -0
- package/dist/service/async-data-service/is-valid.type-test.js +3 -0
- package/dist/service/async-data-service/is-valid.type-test.js.map +1 -0
- package/dist/service/dynamic-service/semantic-service.d.ts +19 -0
- package/dist/service/dynamic-service/semantic-service.js +2 -0
- package/dist/service/dynamic-service/semantic-service.js.map +1 -0
- package/dist/service/semantic-service/semantic-service.d.ts +19 -0
- package/dist/service/semantic-service/semantic-service.js +2 -0
- package/dist/service/semantic-service/semantic-service.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/references/data-lit/README.md +18 -0
- package/references/data-lit/package.json +35 -0
- package/references/data-lit/src/decorators/apply-decorator.ts +26 -0
- package/references/data-lit/src/decorators/apply-service-decorators.ts +15 -0
- package/references/data-lit/src/decorators/index.ts +4 -0
- package/references/data-lit/src/decorators/require-service.ts +20 -0
- package/references/data-lit/src/elements/application-element.ts +42 -0
- package/references/data-lit/src/elements/application-host.ts +43 -0
- package/references/data-lit/src/elements/database-element.ts +42 -0
- package/references/data-lit/src/elements/index.ts +5 -0
- package/references/data-lit/src/functions/index.ts +3 -0
- package/references/data-lit/src/functions/iterate-self-and-ancestors.ts +23 -0
- package/references/data-lit/src/hooks/attach-decorator.ts +32 -0
- package/references/data-lit/src/hooks/component/component.ts +12 -0
- package/references/data-lit/src/hooks/component/stack.ts +19 -0
- package/references/data-lit/src/hooks/index.ts +21 -0
- package/references/data-lit/src/hooks/use-connected.ts +41 -0
- package/references/data-lit/src/hooks/use-debounce.ts +26 -0
- package/references/data-lit/src/hooks/use-drag-observe.ts +59 -0
- package/references/data-lit/src/hooks/use-drag-transaction.ts +46 -0
- package/references/data-lit/src/hooks/use-draggable.ts +112 -0
- package/references/data-lit/src/hooks/use-effect.ts +19 -0
- package/references/data-lit/src/hooks/use-element.ts +83 -0
- package/references/data-lit/src/hooks/use-memo.ts +16 -0
- package/references/data-lit/src/hooks/use-observable-values.ts +10 -0
- package/references/data-lit/src/hooks/use-observable.ts +15 -0
- package/references/data-lit/src/hooks/use-ref.ts +8 -0
- package/references/data-lit/src/hooks/use-resize-observer.ts +31 -0
- package/references/data-lit/src/hooks/use-state.ts +19 -0
- package/references/data-lit/src/hooks/use-updated.ts +56 -0
- package/references/data-lit/src/hooks/use-window-event.ts +16 -0
- package/references/data-lit/src/hooks/with-hooks.ts +22 -0
- package/references/data-lit/src/index.ts +6 -0
- package/references/data-lit/tsconfig.json +11 -0
- package/references/data-lit-todo/package.json +30 -0
- package/references/data-lit-todo/src/elements/todo-list/todo-list-presentation.ts +22 -0
- package/references/data-lit-todo/src/elements/todo-list/todo-list.css.ts +12 -0
- package/references/data-lit-todo/src/elements/todo-list/todo-list.ts +45 -0
- package/references/data-lit-todo/src/elements/todo-row/index.ts +2 -0
- package/references/data-lit-todo/src/elements/todo-row/todo-row-presentation.ts +68 -0
- package/references/data-lit-todo/src/elements/todo-row/todo-row.css.ts +49 -0
- package/references/data-lit-todo/src/elements/todo-row/todo-row.ts +46 -0
- package/references/data-lit-todo/src/elements/todo-toolbar/index.ts +2 -0
- package/references/data-lit-todo/src/elements/todo-toolbar/todo-toolbar-presentation.ts +55 -0
- package/references/data-lit-todo/src/elements/todo-toolbar/todo-toolbar.css.ts +34 -0
- package/references/data-lit-todo/src/elements/todo-toolbar/todo-toolbar.ts +62 -0
- package/references/data-lit-todo/src/elements/todo-undo-redo/index.ts +3 -0
- package/references/data-lit-todo/src/elements/todo-undo-redo/todo-undo-redo-presentation.ts +41 -0
- package/references/data-lit-todo/src/elements/todo-undo-redo/todo-undo-redo.css.ts +12 -0
- package/references/data-lit-todo/src/elements/todo-undo-redo/todo-undo-redo.ts +37 -0
- package/references/data-lit-todo/src/index.ts +9 -0
- package/references/data-lit-todo/src/main.ts +29 -0
- package/references/data-lit-todo/src/sample-types.ts +14 -0
- package/references/data-lit-todo/src/services/dependent-state-service/create-dependent-state-service.ts +8 -0
- package/references/data-lit-todo/src/services/dependent-state-service/dependent-state/all-todos.ts +5 -0
- package/references/data-lit-todo/src/services/dependent-state-service/dependent-state/complete-todos.ts +5 -0
- package/references/data-lit-todo/src/services/dependent-state-service/dependent-state/incomplete-todos.ts +5 -0
- package/references/data-lit-todo/src/services/dependent-state-service/dependent-state/index.ts +4 -0
- package/references/data-lit-todo/src/services/dependent-state-service/dependent-state-service.ts +4 -0
- package/references/data-lit-todo/src/services/main-service/create-main-service.ts +53 -0
- package/references/data-lit-todo/src/services/main-service/todo-main-service.ts +20 -0
- package/references/data-lit-todo/src/services/state-service/create-todo-database.ts +16 -0
- package/references/data-lit-todo/src/services/state-service/create-todo-store.ts +28 -0
- package/references/data-lit-todo/src/services/state-service/todo-state-service.ts +9 -0
- package/references/data-lit-todo/src/services/state-service/transactions/create-bulk-todos.ts +12 -0
- package/references/data-lit-todo/src/services/state-service/transactions/create-todo.test.ts +17 -0
- package/references/data-lit-todo/src/services/state-service/transactions/create-todo.ts +15 -0
- package/references/data-lit-todo/src/services/state-service/transactions/delete-all-todos.ts +18 -0
- package/references/data-lit-todo/src/services/state-service/transactions/delete-todo.test.ts +25 -0
- package/references/data-lit-todo/src/services/state-service/transactions/delete-todo.ts +11 -0
- package/references/data-lit-todo/src/services/state-service/transactions/drag-todo.ts +19 -0
- package/references/data-lit-todo/src/services/state-service/transactions/index.ts +8 -0
- package/references/data-lit-todo/src/services/state-service/transactions/reorder-todos.ts +13 -0
- package/references/data-lit-todo/src/services/state-service/transactions/toggle-complete.test.ts +78 -0
- package/references/data-lit-todo/src/services/state-service/transactions/toggle-complete.ts +15 -0
- package/references/data-lit-todo/src/todo-element.ts +6 -0
- package/references/data-lit-todo/src/todo-host.ts +29 -0
- package/references/data-lit-todo/src/todo-main-element.ts +40 -0
- package/references/data-lit-todo/src/todo-sample.ts +21 -0
- package/references/data-lit-todo/tsconfig.json +10 -0
- package/references/data-react/README.md +47 -0
- package/references/data-react/package.json +36 -0
- package/references/data-react/src/context/database-context.tsx +41 -0
- package/references/data-react/src/hooks/index.ts +5 -0
- package/references/data-react/src/hooks/use-database.ts +13 -0
- package/references/data-react/src/hooks/use-observable-values.ts +15 -0
- package/references/data-react/src/hooks/use-observable.ts +14 -0
- package/references/data-react/src/index.ts +7 -0
- package/references/data-react/tsconfig.json +12 -0
- package/references/data-react-hello/package.json +25 -0
- package/references/data-react-hello/src/App.tsx +13 -0
- package/references/data-react-hello/src/Counter.tsx +21 -0
- package/references/data-react-hello/src/counter-plugin.ts +14 -0
- package/references/data-react-hello/src/main.tsx +9 -0
- package/references/data-react-hello/tsconfig.json +16 -0
- package/references/data-react-pixie/package.json +28 -0
- package/references/data-react-pixie/src/App.tsx +21 -0
- package/references/data-react-pixie/src/bunny.png +0 -0
- package/references/data-react-pixie/src/filter-toggle.tsx +46 -0
- package/references/data-react-pixie/src/filters.ts +22 -0
- package/references/data-react-pixie/src/fox.png +0 -0
- package/references/data-react-pixie/src/hooks/use-database.ts +6 -0
- package/references/data-react-pixie/src/hooks/use-texture.ts +22 -0
- package/references/data-react-pixie/src/main.tsx +14 -0
- package/references/data-react-pixie/src/pixi-react.d.ts +1 -0
- package/references/data-react-pixie/src/pixie-plugin.ts +100 -0
- package/references/data-react-pixie/src/sprite-container.tsx +23 -0
- package/references/data-react-pixie/src/sprite-urls.ts +9 -0
- package/references/data-react-pixie/src/sprite.tsx +35 -0
- package/references/data-react-pixie/src/tick.tsx +10 -0
- package/references/data-react-pixie/src/vite-env.d.ts +6 -0
- package/references/data-react-pixie/tsconfig.json +16 -0
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -296
- package/dist/package.json +0 -183
- package/dist/service/agentic-service/create-from-config.d.ts +0 -45
- package/dist/service/agentic-service/create-from-config.js +0 -85
- package/dist/service/agentic-service/create-from-config.js.map +0 -1
- package/dist/service/agentic-service/create.interface-first-spike.type-test.js +0 -119
- package/dist/service/agentic-service/create.interface-first-spike.type-test.js.map +0 -1
- package/dist/service/agentic-service/index.d.ts +0 -1
- package/dist/service/agentic-service/index.js +0 -3
- package/dist/service/agentic-service/index.js.map +0 -1
- package/dist/service/dynamic-service/create.interface-first-spike.type-test.js +0 -118
- package/dist/service/dynamic-service/create.interface-first-spike.type-test.js.map +0 -1
- /package/dist/{service/agentic-service/create.interface-first-spike.type-test.d.ts → ecs/database/observe-select-deep.type-test.d.ts} +0 -0
- /package/dist/{service/dynamic-service/create.interface-first-spike.type-test.d.ts → ecs/persistence-service/create-storage-persistence-service.test.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/data",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.39",
|
|
4
4
|
"description": "Adobe data oriented programming library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
14
14
|
"README.md",
|
|
15
|
+
"AGENTS.md",
|
|
16
|
+
"references",
|
|
15
17
|
"LICENSE"
|
|
16
18
|
],
|
|
17
19
|
"devDependencies": {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @adobe/data-lit
|
|
2
|
+
|
|
3
|
+
Lit bindings for [@adobe/data](https://www.npmjs.com/package/@adobe/data) — hooks, elements, and decorators for building reactive UIs with the @adobe/data ECS database and observables.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @adobe/data @adobe/data-lit lit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { ApplicationHost, DatabaseElement } from "@adobe/data-lit";
|
|
15
|
+
import { createDatabase } from "@adobe/data/ecs";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
See the `data-lit-todo` sample in this repository for a full example.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adobe/data-lit",
|
|
3
|
+
"version": "0.9.39",
|
|
4
|
+
"description": "Adobe data Lit bindings - hooks, elements, decorators",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"registry": "https://registry.npmjs.org/",
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "cp ../../LICENSE . && tsc -b",
|
|
13
|
+
"dev": "tsc -b -w",
|
|
14
|
+
"link": "pnpm build && pnpm link --global",
|
|
15
|
+
"test": "vitest --run --passWithNoTests",
|
|
16
|
+
"publish-public": "pnpm build && pnpm publish --no-git-checks --access public"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@adobe/data": "workspace:*"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"lit": "^3.3.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"lit": "^3.3.1",
|
|
26
|
+
"typescript": "^5.8.3",
|
|
27
|
+
"vitest": "^1.6.0"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
export function applyDecorator(
|
|
4
|
+
target: any,
|
|
5
|
+
propertyKey: string,
|
|
6
|
+
decorator: (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor
|
|
7
|
+
) {
|
|
8
|
+
// Get the prototype chain
|
|
9
|
+
let currentPrototype = target;
|
|
10
|
+
let descriptor: PropertyDescriptor | undefined;
|
|
11
|
+
|
|
12
|
+
// Walk up the prototype chain until we find the property
|
|
13
|
+
while (currentPrototype && !descriptor) {
|
|
14
|
+
descriptor = Object.getOwnPropertyDescriptor(currentPrototype, propertyKey);
|
|
15
|
+
if (!descriptor) {
|
|
16
|
+
currentPrototype = Object.getPrototypeOf(currentPrototype);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!descriptor) {
|
|
21
|
+
throw new Error(`Property ${propertyKey} not found in prototype chain`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const newDescriptor = decorator(target, propertyKey, descriptor);
|
|
25
|
+
Object.defineProperty(target, propertyKey, newDescriptor);
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { withHooks } from "../hooks/with-hooks.js";
|
|
4
|
+
import { requireService } from "./require-service.js";
|
|
5
|
+
import { TemplateResult } from "lit";
|
|
6
|
+
|
|
7
|
+
export function applyServiceDecorators(target: any) {
|
|
8
|
+
const prototype = Object.getPrototypeOf(target);
|
|
9
|
+
const originalRender = target.render ?? prototype.render;
|
|
10
|
+
const withService = requireService()(target, 'render', {
|
|
11
|
+
value: originalRender
|
|
12
|
+
});
|
|
13
|
+
const withHooksAndService = withHooks(target, 'render', withService);
|
|
14
|
+
target.render = withHooksAndService.value as () => TemplateResult | null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
export function requireService() {
|
|
4
|
+
return function (
|
|
5
|
+
target: any,
|
|
6
|
+
propertyKey: string,
|
|
7
|
+
descriptor: PropertyDescriptor
|
|
8
|
+
) {
|
|
9
|
+
const originalRender = descriptor.value;
|
|
10
|
+
|
|
11
|
+
descriptor.value = function (this: any) {
|
|
12
|
+
if (!this.service) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return originalRender.call(this);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return descriptor;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { LitElement } from 'lit';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { attachDecorator, withHooks } from '../hooks/index.js';
|
|
6
|
+
import { iterateSelfAndAncestors } from '../functions/index.js';
|
|
7
|
+
import { Service, isService } from '@adobe/data/service';
|
|
8
|
+
|
|
9
|
+
export class ApplicationElement<MainService extends Service> extends LitElement {
|
|
10
|
+
@property({ type: Object, reflect: false })
|
|
11
|
+
service!: MainService;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
attachDecorator(this, 'render', withHooks);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
connectedCallback(): void {
|
|
19
|
+
super.connectedCallback();
|
|
20
|
+
|
|
21
|
+
if (!this.service) {
|
|
22
|
+
const service = this.findAncestorService();
|
|
23
|
+
if (service) {
|
|
24
|
+
this.service = service;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected findAncestorService(): MainService | void {
|
|
30
|
+
for (const element of iterateSelfAndAncestors(this)) {
|
|
31
|
+
const { service } = element as Partial<ApplicationElement<MainService>>;
|
|
32
|
+
if (isService(service)) {
|
|
33
|
+
return service;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public override render() {
|
|
39
|
+
throw new Error('render function must be overridden');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { LitElement, nothing, TemplateResult, css } from 'lit';
|
|
4
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
5
|
+
import { Service } from '@adobe/data/service';
|
|
6
|
+
import { ApplicationElement } from './application-element.js';
|
|
7
|
+
|
|
8
|
+
const tagName = "application-host";
|
|
9
|
+
|
|
10
|
+
declare global {
|
|
11
|
+
interface HTMLElementTagNameMap {
|
|
12
|
+
'application-element': ApplicationElement<Service>;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@customElement(tagName)
|
|
17
|
+
export class ApplicationHost<MainService extends Service = Service> extends LitElement {
|
|
18
|
+
static styles = css`
|
|
19
|
+
:host {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex: 1 1 auto;
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
@property()
|
|
26
|
+
createService!: () => Promise<MainService>;
|
|
27
|
+
|
|
28
|
+
@property({})
|
|
29
|
+
renderElement!: () => TemplateResult;
|
|
30
|
+
|
|
31
|
+
@property({ attribute: false })
|
|
32
|
+
public service!: MainService;
|
|
33
|
+
|
|
34
|
+
override async connectedCallback() {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.service = await this.createService();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override render() {
|
|
40
|
+
return this.service ? this.renderElement() : nothing;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { LitElement } from 'lit';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { iterateSelfAndAncestors } from '../functions/index.js';
|
|
6
|
+
import { Database } from '@adobe/data/ecs';
|
|
7
|
+
import { attachDecorator, withHooks } from '../index.js';
|
|
8
|
+
|
|
9
|
+
export abstract class DatabaseElement<P extends Database.Plugin> extends LitElement {
|
|
10
|
+
|
|
11
|
+
@property({ type: Object, reflect: false })
|
|
12
|
+
service!: Database.Plugin.ToDatabase<P>;
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
attachDecorator(this, 'render', withHooks);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
abstract get plugin(): P;
|
|
20
|
+
|
|
21
|
+
connectedCallback(): void {
|
|
22
|
+
if (!this.service) {
|
|
23
|
+
const service = this.findAncestorDatabase();
|
|
24
|
+
this.service = (service?.extend(this.plugin) ?? Database.create(this.plugin)) as unknown as Database.Plugin.ToDatabase<P>;
|
|
25
|
+
}
|
|
26
|
+
super.connectedCallback();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected findAncestorDatabase(): Database | void {
|
|
30
|
+
for (const element of iterateSelfAndAncestors(this)) {
|
|
31
|
+
const { service } = element as Partial<DatabaseElement<any>>;
|
|
32
|
+
if (Database.is(service)) {
|
|
33
|
+
return service;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public override render() {
|
|
39
|
+
throw new Error('render function must be overridden');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
export function* iterateSelfAndAncestors(element: Element): IterableIterator<Element> {
|
|
4
|
+
let current: Element | null = element;
|
|
5
|
+
|
|
6
|
+
while (current) {
|
|
7
|
+
yield current;
|
|
8
|
+
|
|
9
|
+
if (current instanceof HTMLSlotElement && current.assignedSlot) {
|
|
10
|
+
// Move to the slot's parent if the current element is assigned to a slot
|
|
11
|
+
current = current.assignedSlot;
|
|
12
|
+
} else if (current.parentNode instanceof Element) {
|
|
13
|
+
// Move up to the parent node if it is an element
|
|
14
|
+
current = current.parentNode;
|
|
15
|
+
} else if ((current.getRootNode() as ShadowRoot).host) {
|
|
16
|
+
// Move to the host element if we're at a shadow root
|
|
17
|
+
current = (current.getRootNode() as ShadowRoot).host;
|
|
18
|
+
} else {
|
|
19
|
+
// If no more ancestors, stop the iteration
|
|
20
|
+
current = null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Attacheds a decorator to a method on an object and reassigns the resulting value back to the object.
|
|
5
|
+
*/
|
|
6
|
+
export function attachDecorator<T, K extends keyof T>(
|
|
7
|
+
obj: T,
|
|
8
|
+
property: K,
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
10
|
+
decorator: (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<T[K]>) => PropertyDescriptor
|
|
11
|
+
): void {
|
|
12
|
+
// Get the descriptor of the property
|
|
13
|
+
let descriptor = Object.getOwnPropertyDescriptor(obj, property);
|
|
14
|
+
|
|
15
|
+
if (!descriptor) {
|
|
16
|
+
if (!obj[property]) {
|
|
17
|
+
throw new Error(`Property ${property.toString()} does not exist on object`);
|
|
18
|
+
}
|
|
19
|
+
descriptor = {
|
|
20
|
+
value: obj[property],
|
|
21
|
+
writable: true,
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Apply the decorator to the descriptor
|
|
28
|
+
const decoratedDescriptor = decorator(obj, String(property), descriptor);
|
|
29
|
+
|
|
30
|
+
// Reassign the decorated method back to the object
|
|
31
|
+
obj[property] = decoratedDescriptor.value;
|
|
32
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
export interface Component extends EventTarget {
|
|
4
|
+
/**
|
|
5
|
+
* Is this component active and connected to the containing dom?
|
|
6
|
+
*/
|
|
7
|
+
readonly isConnected: boolean;
|
|
8
|
+
hookIndex: number
|
|
9
|
+
hooks: any[]
|
|
10
|
+
updatedListeners: Set<() => void>
|
|
11
|
+
requestUpdate(): void
|
|
12
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import type { Component } from "./component.js";
|
|
4
|
+
|
|
5
|
+
const activeComponentStack: Component[] = [];
|
|
6
|
+
export const Component_stack = {
|
|
7
|
+
active(): Component {
|
|
8
|
+
return activeComponentStack[activeComponentStack.length - 1]!;
|
|
9
|
+
},
|
|
10
|
+
push(component: Component) {
|
|
11
|
+
component.hookIndex = 0;
|
|
12
|
+
component.hooks ??= [];
|
|
13
|
+
activeComponentStack.push(component)
|
|
14
|
+
},
|
|
15
|
+
pop() {
|
|
16
|
+
activeComponentStack.pop()
|
|
17
|
+
}
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
export * from "./component/component.js";
|
|
4
|
+
export * from "./component/stack.js";
|
|
5
|
+
export * from "./use-state.js";
|
|
6
|
+
export * from "./use-effect.js";
|
|
7
|
+
export * from "./use-connected.js";
|
|
8
|
+
export * from "./use-memo.js";
|
|
9
|
+
export * from "./use-ref.js";
|
|
10
|
+
export * from "./use-observable-values.js";
|
|
11
|
+
export * from "./use-observable.js";
|
|
12
|
+
export * from "./use-window-event.js";
|
|
13
|
+
export * from "./use-resize-observer.js";
|
|
14
|
+
export * from "./use-debounce.js";
|
|
15
|
+
export * from "./use-element.js";
|
|
16
|
+
export * from "./with-hooks.js";
|
|
17
|
+
export * from "./attach-decorator.js";
|
|
18
|
+
export * from "./use-drag-transaction.js";
|
|
19
|
+
export * from "./use-drag-observe.js";
|
|
20
|
+
export * from "./use-draggable.js";
|
|
21
|
+
export * from "./use-updated.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import type { EffectCallback } from "./use-effect.js";
|
|
4
|
+
import { useEffect } from "./use-effect.js";
|
|
5
|
+
import { Component_stack } from "./component/stack.js";
|
|
6
|
+
|
|
7
|
+
export function useConnected(callback: EffectCallback, dependencies?: unknown[]) {
|
|
8
|
+
const component = Component_stack.active();
|
|
9
|
+
|
|
10
|
+
let disconnect: (() => void) | void;
|
|
11
|
+
function onConnect() {
|
|
12
|
+
if (!disconnect) {
|
|
13
|
+
disconnect = callback();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function onDisconnect() {
|
|
18
|
+
if (disconnect) {
|
|
19
|
+
disconnect?.();
|
|
20
|
+
disconnect = undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO
|
|
25
|
+
if (component.isConnected) {
|
|
26
|
+
onConnect();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
component.addEventListener("connected", onConnect);
|
|
31
|
+
component.addEventListener("disconnected", onDisconnect);
|
|
32
|
+
|
|
33
|
+
return () => {
|
|
34
|
+
component.removeEventListener("connected", onConnect);
|
|
35
|
+
component.removeEventListener("disconnected", onDisconnect);
|
|
36
|
+
|
|
37
|
+
onDisconnect();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}, dependencies);
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "./use-effect.js";
|
|
4
|
+
import { useState } from "./use-state.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook to debounce a value. Returns the debounced value after the specified delay.
|
|
8
|
+
*
|
|
9
|
+
* @param value - The value to debounce
|
|
10
|
+
* @param delay - Delay in milliseconds before updating the debounced value
|
|
11
|
+
* @returns The debounced value
|
|
12
|
+
*/
|
|
13
|
+
export function useDebounce<T>(value: T, delay: number): T {
|
|
14
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const timeoutId = window.setTimeout(() => {
|
|
18
|
+
setDebouncedValue(value);
|
|
19
|
+
}, delay);
|
|
20
|
+
|
|
21
|
+
return () => clearTimeout(timeoutId);
|
|
22
|
+
}, [value, delay]);
|
|
23
|
+
|
|
24
|
+
return debouncedValue;
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { DraggableProps, useDraggable } from './use-draggable.js';
|
|
4
|
+
import { useElement } from './use-element.js';
|
|
5
|
+
import { Observe } from '@adobe/data/observe';
|
|
6
|
+
import { Vec2 } from '@adobe/data/math';
|
|
7
|
+
|
|
8
|
+
export type DragObserveProps = Pick<
|
|
9
|
+
DraggableProps,
|
|
10
|
+
'minDragDistance' | 'dragCursor' | 'addPlaceholder' | 'stopPropagation'
|
|
11
|
+
>;
|
|
12
|
+
export type DragStart = {
|
|
13
|
+
readonly type: 'start' | 'cancel';
|
|
14
|
+
};
|
|
15
|
+
export type DragMove = {
|
|
16
|
+
readonly type: 'move';
|
|
17
|
+
readonly delta: Vec2;
|
|
18
|
+
readonly position: Vec2;
|
|
19
|
+
};
|
|
20
|
+
export type DragEnd = {
|
|
21
|
+
readonly type: 'end';
|
|
22
|
+
readonly delta: Vec2;
|
|
23
|
+
readonly position: Vec2;
|
|
24
|
+
};
|
|
25
|
+
export type DragState = DragStart | DragMove | DragEnd;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* This hook creates a drag observe function that can be used to observe the drag state of an element.
|
|
29
|
+
* This is normally not used directly, but rather through the `useDragTransaction` hook.
|
|
30
|
+
* @param props
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
export function useDragObserve(props: DragObserveProps, dependencies: unknown[]) {
|
|
34
|
+
const [dragState, setDragState] = Observe.createEvent<DragState>();
|
|
35
|
+
const element = useElement();
|
|
36
|
+
useDraggable(element,
|
|
37
|
+
{
|
|
38
|
+
...props,
|
|
39
|
+
onDragStart: _e => {
|
|
40
|
+
setDragState({ type: 'start' });
|
|
41
|
+
},
|
|
42
|
+
onDrag: (_e, position, delta) => {
|
|
43
|
+
setDragState({
|
|
44
|
+
type: 'move',
|
|
45
|
+
position,
|
|
46
|
+
delta,
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
onDragEnd: (_e, position, delta) => {
|
|
50
|
+
setDragState({ type: 'end', position, delta });
|
|
51
|
+
},
|
|
52
|
+
onDragCancel: () => {
|
|
53
|
+
setDragState({ type: 'cancel' });
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
dependencies
|
|
57
|
+
);
|
|
58
|
+
return dragState;
|
|
59
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
|
|
3
|
+
import { DragEnd, DragMove, DragObserveProps, useDragObserve } from './use-drag-observe.js';
|
|
4
|
+
import { useEffect } from "./use-effect.js";
|
|
5
|
+
import type { AsyncArgsProvider } from '@adobe/data/ecs';
|
|
6
|
+
import { Observe } from '@adobe/data/observe';
|
|
7
|
+
|
|
8
|
+
export type DragTransactionProps<T> = DragObserveProps & {
|
|
9
|
+
transaction: (asyncArgs: AsyncArgsProvider<T>) => void;
|
|
10
|
+
update: (drag: DragMove | DragEnd) => T | void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function useDragTransaction<T>(props: DragTransactionProps<T>, dependencies: unknown[]) {
|
|
14
|
+
const { transaction, update } = props;
|
|
15
|
+
const dragObserve = useDragObserve(props, dependencies);
|
|
16
|
+
const startDragTransaction = () => {
|
|
17
|
+
let done = false;
|
|
18
|
+
// we start the transaction by calling it with an async generator that will yield the args asynchronously
|
|
19
|
+
transaction(
|
|
20
|
+
// we create the async generator by mapping the dragObserve state changes to transaction args
|
|
21
|
+
() =>
|
|
22
|
+
Observe.toAsyncGenerator(
|
|
23
|
+
// this uses the withMap function and the provided update and finish functions
|
|
24
|
+
// any type 'start' will just be ignored and filtered out
|
|
25
|
+
Observe.withFilter(dragObserve, value => {
|
|
26
|
+
if (value.type === 'end') {
|
|
27
|
+
done = true;
|
|
28
|
+
return update(value);
|
|
29
|
+
}
|
|
30
|
+
if (value.type === 'move') {
|
|
31
|
+
return update(value);
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
_value => done
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
// now we will observe the drag state and start a new transaction whenever a drag starts
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
return dragObserve(value => {
|
|
41
|
+
if (value.type === 'start') {
|
|
42
|
+
startDragTransaction();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}, dependencies);
|
|
46
|
+
}
|