@excom/abortable-element 0.1.0

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 (28) hide show
  1. package/.rush/temp/chunked-rush-logs/abortable-element.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/abortable-element.build_docs.chunks.jsonl +1 -0
  3. package/.rush/temp/chunked-rush-logs/abortable-element.build_package-metas.chunks.jsonl +1 -0
  4. package/.rush/temp/operation/apply-exports/all.log +1 -0
  5. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  6. package/.rush/temp/operation/apply-exports/state.json +3 -0
  7. package/.rush/temp/operation/build_docs/all.log +1 -0
  8. package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
  9. package/.rush/temp/operation/build_docs/state.json +3 -0
  10. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  11. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  12. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  13. package/.rush/temp/shrinkwrap-deps.json +3 -0
  14. package/config/rig.json +6 -0
  15. package/index.ts +22 -0
  16. package/package.json +44 -0
  17. package/rush-logs/abortable-element.apply-exports.cache.log +1 -0
  18. package/rush-logs/abortable-element.apply-exports.log +1 -0
  19. package/rush-logs/abortable-element.build_docs.cache.log +1 -0
  20. package/rush-logs/abortable-element.build_docs.log +1 -0
  21. package/rush-logs/abortable-element.build_package-metas.cache.log +1 -0
  22. package/rush-logs/abortable-element.build_package-metas.log +1 -0
  23. package/support/custom-elements.json +27 -0
  24. package/support/dist-docs/abortable-element.md +72 -0
  25. package/support/docs/README.md +53 -0
  26. package/support/package-meta.json +49 -0
  27. package/support/tests/abortable-element.test.ts +58 -0
  28. package/tsconfig.json +5 -0
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 34.980425000000196
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 42.77186799999993
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 86.987795
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "../../packages/abortable-element": "../../packages/abortable-element:YAC8G8l1nkKknuTXH370JI0/DynCPkP81MNQcvbO6fA=:"
3
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
3
+ "rigPackageName": "@excom/heft-rig",
4
+ "rigProfile": "default"
5
+ }
6
+
package/index.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { Neutron } from "@excom/neutron";
2
+
3
+ /**
4
+ * Composition base that owns an `AbortController` for cancellable async work. Subclasses call `doAbort()` to cancel in-flight operations and rotate a fresh controller. Used by `RenderableElement` (and thus `<include-content>`, `<spa-route>`) when template fetches are superseded.
5
+ *
6
+ * @summary AbortController ownership for Neutron elements.
7
+ */
8
+ export const AbortableElement = Neutron({
9
+ tag: "noop-tag",
10
+ props: {
11
+ // private state
12
+ abortController: {
13
+ type: AbortController,
14
+ defaultValue: () => new AbortController(),
15
+ },
16
+ },
17
+ }).defineMethods({
18
+ doAbort: ({ abortController }, reason?: any) => {
19
+ abortController?.abort(reason);
20
+ return { abortController: new AbortController() };
21
+ },
22
+ });
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@excom/abortable-element",
3
+ "version": "0.1.0",
4
+ "description": "AbortableElement base for Neutron elements",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": ">=24.13.0"
8
+ },
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@excom/neutron": "^0.1.0"
12
+ },
13
+ "peerDependencies": {},
14
+ "devDependencies": {
15
+ "@excom/heft-rig": "^0.1.0"
16
+ },
17
+ "repository": {
18
+ "url": "excom-dev/nucleus",
19
+ "directory": "packages/abortable-element"
20
+ },
21
+ "homepage": "https://github.com/excom-dev/nucleus/tree/main/packages/abortable-element/support/docs/README.md",
22
+ "bugs": "https://github.com/excom-dev/nucleus/issues",
23
+ "keywords": [
24
+ "AbortableElement",
25
+ "abortable-element",
26
+ "neutron",
27
+ "kit-element-base",
28
+ "custom-elements"
29
+ ],
30
+ "excom": {
31
+ "packageType": "element-base"
32
+ },
33
+ "scripts": {
34
+ "build": "node node_modules/@excom/heft-rig/scripts/vite-build.mjs",
35
+ "build:watch": "node node_modules/@excom/heft-rig/scripts/vite-build-watch.mjs",
36
+ "format": "node node_modules/@excom/heft-rig/scripts/format.mjs",
37
+ "test": "node node_modules/@excom/heft-rig/scripts/vitest.mjs",
38
+ "coverage": "node node_modules/@excom/heft-rig/scripts/coverage.mjs",
39
+ "dev": "node node_modules/@excom/heft-rig/scripts/vite-dev.mjs",
40
+ "preview": "node node_modules/@excom/heft-rig/scripts/vite-preview.mjs",
41
+ "build:package-metas": "node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs",
42
+ "build:docs": "node node_modules/@excom/heft-rig/scripts/build-docs.mjs"
43
+ }
44
+ }
@@ -0,0 +1 @@
1
+ Caching has been disabled for this project's "apply-exports" command.
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:docs" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:package-metas" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
@@ -0,0 +1,27 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "modules": [
4
+ {
5
+ "kind": "javascript-module",
6
+ "path": "index.ts",
7
+ "declarations": [
8
+ {
9
+ "kind": "mixin",
10
+ "name": "AbortableElement",
11
+ "summary": "AbortController ownership for Neutron elements.",
12
+ "description": "Composition base that owns an `AbortController` for cancellable async work. Subclasses call `doAbort()` to cancel in-flight operations and rotate a fresh controller. Used by `RenderableElement` (and thus `<include-content>`, `<spa-route>`) when template fetches are superseded."
13
+ }
14
+ ],
15
+ "exports": [
16
+ {
17
+ "kind": "js",
18
+ "name": "AbortableElement",
19
+ "declaration": {
20
+ "name": "AbortableElement",
21
+ "module": "index.ts"
22
+ }
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,72 @@
1
+ # abortable-element
2
+
3
+ AbortController ownership for Neutron elements — cancel in-flight
4
+ work cleanly when a newer request supersedes it.
5
+
6
+ ## Features
7
+
8
+ - **Owned controller** Fresh `AbortController` per in-flight cycle
9
+ - **doAbort()** Abort current work and rotate a new controller
10
+ - **Fetch-ready** Pass `abortController.signal` into `fetch` /
11
+ template loads
12
+
13
+ ## Installation
14
+
15
+
16
+ `@excom/abortable-element` v0.1.0
17
+
18
+ ```bash
19
+ pnpm add @excom/abortable-element
20
+ ```
21
+
22
+ ```bash
23
+ npm install @excom/abortable-element
24
+ ```
25
+
26
+ ```bash
27
+ yarn add @excom/abortable-element
28
+ ```
29
+
30
+ ### Import
31
+
32
+ ```ts
33
+ import { /* … */ } from "@excom/abortable-element";
34
+ ```
35
+
36
+
37
+
38
+ ## Usage
39
+
40
+ Compose `AbortableElement` and pass `abortController.signal` into
41
+ async work. Call `doAbort()` when that work should be cancelled (e.g.
42
+ `template-ref` changed). `RenderableElement` already does this for
43
+ template fetches.
44
+
45
+ ```ts
46
+ import { Neutron } from "@excom/neutron";
47
+ import { AbortableElement } from "@excom/abortable-element";
48
+
49
+ export const FetchOnce = Neutron.compose([
50
+ AbortableElement,
51
+ Neutron({
52
+ tag: "fetch-once",
53
+ props: { src: String },
54
+ }),
55
+ ])
56
+ .onPropChanged("src", async (el) => {
57
+ el.doAbort();
58
+ if (!el.src) return;
59
+ const res = await fetch(el.src, {
60
+ signal: el.abortController.signal,
61
+ });
62
+ // …
63
+ });
64
+
65
+ FetchOnce.define();
66
+ ```
67
+
68
+ There are no public attributes — the controller is internal. See
69
+ [renderable-element](/nucleus/packages/renderable-element) for the primary
70
+ consumer.
71
+
72
+ ### API Reference
@@ -0,0 +1,53 @@
1
+ # abortable-element
2
+
3
+ AbortController ownership for Neutron elements — cancel in-flight
4
+ work cleanly when a newer request supersedes it.
5
+
6
+ ## Features
7
+
8
+ - **Owned controller** Fresh `AbortController` per in-flight cycle
9
+ - **doAbort()** Abort current work and rotate a new controller
10
+ - **Fetch-ready** Pass `abortController.signal` into `fetch` /
11
+ template loads
12
+
13
+ ## Installation
14
+
15
+ <include-content is-active template-ref="/views/install-section/install-section.html"></include-content>
16
+
17
+ ## Usage
18
+
19
+ Compose `AbortableElement` and pass `abortController.signal` into
20
+ async work. Call `doAbort()` when that work should be cancelled (e.g.
21
+ `template-ref` changed). `RenderableElement` already does this for
22
+ template fetches.
23
+
24
+ ```ts
25
+ import { Neutron } from "@excom/neutron";
26
+ import { AbortableElement } from "@excom/abortable-element";
27
+
28
+ export const FetchOnce = Neutron.compose([
29
+ AbortableElement,
30
+ Neutron({
31
+ tag: "fetch-once",
32
+ props: { src: String },
33
+ }),
34
+ ])
35
+ .onPropChanged("src", async (el) => {
36
+ el.doAbort();
37
+ if (!el.src) return;
38
+ const res = await fetch(el.src, {
39
+ signal: el.abortController.signal,
40
+ });
41
+ // …
42
+ });
43
+
44
+ FetchOnce.define();
45
+ ```
46
+
47
+ There are no public attributes — the controller is internal. See
48
+ [renderable-element](/nucleus/packages/renderable-element) for the primary
49
+ consumer.
50
+
51
+ ### API Reference
52
+
53
+ <include-content is-active template-ref="/views/api-reference/api-reference.html"></include-content>
@@ -0,0 +1,49 @@
1
+ {
2
+ "shortName": "abortable-element",
3
+ "package": {
4
+ "name": "@excom/abortable-element",
5
+ "version": "0.1.0",
6
+ "description": "AbortableElement base for Neutron elements",
7
+ "peerDependencies": {},
8
+ "excom": {
9
+ "packageType": "element-base"
10
+ }
11
+ },
12
+ "demos": {},
13
+ "readme": "<h1 id=\"md-abortable-element\">abortable-element</h1>\n<p>AbortController ownership for Neutron elements — cancel in-flight\nwork cleanly when a newer request supersedes it.</p>\n<h2 id=\"md-features\">Features</h2>\n<ul>\n<li><strong>Owned controller</strong> Fresh <code>AbortController</code> per in-flight cycle</li>\n<li><strong>doAbort()</strong> Abort current work and rotate a new controller</li>\n<li><strong>Fetch-ready</strong> Pass <code>abortController.signal</code> into <code>fetch</code> /\ntemplate loads</li>\n</ul>\n<h2 id=\"md-installation\">Installation</h2>\n<p><include-content is-active template-ref=\"/views/install-section/install-section.html\"></include-content></p>\n<h2 id=\"md-usage\">Usage</h2>\n<p>Compose <code>AbortableElement</code> and pass <code>abortController.signal</code> into\nasync work. Call <code>doAbort()</code> when that work should be cancelled (e.g.\n<code>template-ref</code> changed). <code>RenderableElement</code> already does this for\ntemplate fetches.</p>\n<include-content data-language=\"ts\"><template>import { Neutron } from \"@excom/neutron\";\nimport { AbortableElement } from \"@excom/abortable-element\";\n\nexport const FetchOnce = Neutron.compose([\n AbortableElement,\n Neutron({\n tag: \"fetch-once\",\n props: { src: String },\n }),\n])\n .onPropChanged(\"src\", async (el) =&gt; {\n el.doAbort();\n if (!el.src) return;\n const res = await fetch(el.src, {\n signal: el.abortController.signal,\n });\n // …\n });\n\nFetchOnce.define();</template></include-content>\n<p>There are no public attributes — the controller is internal. See\n<spa-a route-href=\"/nucleus/packages/renderable-element\" role=\"link\">renderable-element</spa-a> for the primary\nconsumer.</p>\n<h3 id=\"md-api-reference\">API Reference</h3>\n<p><include-content is-active template-ref=\"/views/api-reference/api-reference.html\"></include-content></p>\n",
14
+ "docs": {
15
+ "readme": "<h1 id=\"md-abortable-element\">abortable-element</h1>\n<p>AbortController ownership for Neutron elements — cancel in-flight\nwork cleanly when a newer request supersedes it.</p>\n<h2 id=\"md-features\">Features</h2>\n<ul>\n<li><strong>Owned controller</strong> Fresh <code>AbortController</code> per in-flight cycle</li>\n<li><strong>doAbort()</strong> Abort current work and rotate a new controller</li>\n<li><strong>Fetch-ready</strong> Pass <code>abortController.signal</code> into <code>fetch</code> /\ntemplate loads</li>\n</ul>\n<h2 id=\"md-installation\">Installation</h2>\n<p><include-content is-active template-ref=\"/views/install-section/install-section.html\"></include-content></p>\n<h2 id=\"md-usage\">Usage</h2>\n<p>Compose <code>AbortableElement</code> and pass <code>abortController.signal</code> into\nasync work. Call <code>doAbort()</code> when that work should be cancelled (e.g.\n<code>template-ref</code> changed). <code>RenderableElement</code> already does this for\ntemplate fetches.</p>\n<include-content data-language=\"ts\"><template>import { Neutron } from \"@excom/neutron\";\nimport { AbortableElement } from \"@excom/abortable-element\";\n\nexport const FetchOnce = Neutron.compose([\n AbortableElement,\n Neutron({\n tag: \"fetch-once\",\n props: { src: String },\n }),\n])\n .onPropChanged(\"src\", async (el) =&gt; {\n el.doAbort();\n if (!el.src) return;\n const res = await fetch(el.src, {\n signal: el.abortController.signal,\n });\n // …\n });\n\nFetchOnce.define();</template></include-content>\n<p>There are no public attributes — the controller is internal. See\n<spa-a route-href=\"/nucleus/packages/renderable-element\" role=\"link\">renderable-element</spa-a> for the primary\nconsumer.</p>\n<h3 id=\"md-api-reference\">API Reference</h3>\n<p><include-content is-active template-ref=\"/views/api-reference/api-reference.html\"></include-content></p>\n"
16
+ },
17
+ "installation": {
18
+ "name": "@excom/abortable-element",
19
+ "shortName": "abortable-element",
20
+ "version": "0.1.0",
21
+ "description": "AbortableElement base for Neutron elements",
22
+ "packageType": "element-base",
23
+ "install": {
24
+ "npm": "npm install @excom/abortable-element"
25
+ },
26
+ "imports": {
27
+ "js": "import { /* … */ } from \"@excom/abortable-element\";"
28
+ },
29
+ "peerDependencies": []
30
+ },
31
+ "elementApis": [
32
+ {
33
+ "summary": "AbortController ownership for Neutron elements.",
34
+ "kind": "mixin",
35
+ "attributes": [],
36
+ "events": [],
37
+ "slots": [],
38
+ "cssProperties": [],
39
+ "cssClasses": [],
40
+ "cssAliases": [],
41
+ "listens": [],
42
+ "commands": [],
43
+ "defaultActions": [],
44
+ "expectedChildren": [],
45
+ "provisions": []
46
+ }
47
+ ],
48
+ "exportedFiles": {}
49
+ }
@@ -0,0 +1,58 @@
1
+ import { AbortableElement } from "../../index";
2
+ import {
3
+ afterEach,
4
+ describe,
5
+ expect,
6
+ fixture,
7
+ it,
8
+ } from "@excom/heft-rig/profiles/default/config/test-utils";
9
+
10
+ const TAG = "abortable-element-test";
11
+ if (!customElements.get(TAG)) {
12
+ AbortableElement.define(TAG);
13
+ }
14
+
15
+ describe("AbortableElement", () => {
16
+ afterEach(() => {
17
+ document.body.innerHTML = "";
18
+ });
19
+
20
+ it("has a fresh AbortController by default", () => {
21
+ const el = fixture<any>(`<${TAG}></${TAG}>`);
22
+ expect(el.abortController).toBeInstanceOf(AbortController);
23
+ expect(el.abortController.signal.aborted).toBe(false);
24
+ });
25
+
26
+ it("aborts and returns a fresh controller", () => {
27
+ const el = fixture<any>(`<${TAG}></${TAG}>`);
28
+ const initial = el.abortController;
29
+ expect(initial).toBeInstanceOf(AbortController);
30
+ el.doAbort("test");
31
+ expect(initial.signal.aborted).toBe(true);
32
+ expect(el.abortController).toBeInstanceOf(AbortController);
33
+ expect(el.abortController).not.toBe(initial);
34
+ expect(el.abortController.signal.aborted).toBe(false);
35
+ });
36
+
37
+ it("passes abort reason to the signal", () => {
38
+ const el = fixture<any>(`<${TAG}></${TAG}>`);
39
+ const controller = el.abortController;
40
+ el.doAbort("custom-reason");
41
+ expect(controller.signal.aborted).toBe(true);
42
+ expect(controller.signal.reason).toBe("custom-reason");
43
+ });
44
+
45
+ it("can abort multiple times, each producing a new controller", () => {
46
+ const el = fixture<any>(`<${TAG}></${TAG}>`);
47
+ const first = el.abortController;
48
+ el.doAbort();
49
+ const second = el.abortController;
50
+ el.doAbort();
51
+ const third = el.abortController;
52
+ expect(first).not.toBe(second);
53
+ expect(second).not.toBe(third);
54
+ expect(first.signal.aborted).toBe(true);
55
+ expect(second.signal.aborted).toBe(true);
56
+ expect(third.signal.aborted).toBe(false);
57
+ });
58
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "@excom/heft-rig/profiles/default/config/tsconfig.json",
3
+ "include": ["./*.ts"],
4
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
5
+ }