@excom/neutron 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 (63) hide show
  1. package/.rush/temp/chunked-rush-logs/neutron.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/neutron.build_package-metas.chunks.jsonl +1 -0
  3. package/.rush/temp/operation/apply-exports/all.log +1 -0
  4. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  5. package/.rush/temp/operation/apply-exports/state.json +3 -0
  6. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  7. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  8. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  9. package/.rush/temp/shrinkwrap-deps.json +3 -0
  10. package/config/rig.json +6 -0
  11. package/index.ts +9 -0
  12. package/package.json +45 -0
  13. package/rush-logs/neutron.apply-exports.cache.log +1 -0
  14. package/rush-logs/neutron.apply-exports.log +1 -0
  15. package/rush-logs/neutron.build_package-metas.cache.log +1 -0
  16. package/rush-logs/neutron.build_package-metas.log +1 -0
  17. package/src/command.ts +102 -0
  18. package/src/common-element.ts +377 -0
  19. package/src/constants.ts +101 -0
  20. package/src/devtools-hook.ts +93 -0
  21. package/src/lifecycle-configs.ts +304 -0
  22. package/src/neutron-element.ts +72 -0
  23. package/src/neutron-error.ts +6 -0
  24. package/src/neutron-internal.ts +550 -0
  25. package/src/neutron.ts +36 -0
  26. package/src/types/effect.types.ts +104 -0
  27. package/src/types/element.types.ts +263 -0
  28. package/src/types/index.ts +4 -0
  29. package/src/types/new.types.ts +159 -0
  30. package/src/types/shared.types.ts +25 -0
  31. package/src/utils/effect.ts +357 -0
  32. package/src/utils/element.ts +382 -0
  33. package/src/utils/index.ts +2 -0
  34. package/support/docs/COMMANDS.md +58 -0
  35. package/support/docs/COMPOSE.md +32 -0
  36. package/support/docs/DEBUG.md +11 -0
  37. package/support/docs/DEFINE.md +20 -0
  38. package/support/docs/EFFECTS.md +49 -0
  39. package/support/docs/EVENTS.md +57 -0
  40. package/support/docs/LIFECYCLES.md +69 -0
  41. package/support/docs/METHODS.md +49 -0
  42. package/support/docs/PROMISE_PROPS.md +29 -0
  43. package/support/docs/PROPS.md +64 -0
  44. package/support/docs/PROP_REACTIONS.md +35 -0
  45. package/support/docs/PROVISION.md +31 -0
  46. package/support/docs/README.md +118 -0
  47. package/support/docs/RECOMPOSE.md +70 -0
  48. package/support/docs/TYPESCRIPT.md +51 -0
  49. package/support/docs-sections.json +42 -0
  50. package/support/package-meta.json +129 -0
  51. package/support/tests/commands.test.ts +330 -0
  52. package/support/tests/common-element.test.ts +342 -0
  53. package/support/tests/devtools-hook.test.ts +209 -0
  54. package/support/tests/devtools-renderer.test.ts +125 -0
  55. package/support/tests/effects.test.ts +253 -0
  56. package/support/tests/element-config.test.ts +331 -0
  57. package/support/tests/entry.test.ts +68 -0
  58. package/support/tests/lifecycles.test.ts +489 -0
  59. package/support/tests/loop-guard.test.ts +162 -0
  60. package/support/tests/neutron.test.ts +1286 -0
  61. package/support/tests/recompose.test.ts +129 -0
  62. package/support/tests/utils.test.ts +75 -0
  63. package/tsconfig.json +5 -0
@@ -0,0 +1,129 @@
1
+ import { Neutron } from "../../src/neutron";
2
+ import {
3
+ describe,
4
+ expect,
5
+ it,
6
+ vi,
7
+ } from "@excom/heft-rig/node_modules/vitest";
8
+ import { wait } from "@excom/heft-rig/profiles/default/config/test-utils";
9
+
10
+ /**
11
+ * "Recomposition": an app author imports a package's raw builder (the
12
+ * element source file, not the `index.ts` that calls `.define()`), edits its
13
+ * lifecycles / methods / config, and only then registers it.
14
+ */
15
+
16
+ // What a package's raw source file would export.
17
+ const onConnectedOriginal = vi.fn(() => ({ isReady: true }));
18
+ const onTickSetOriginal = vi.fn(() => ({ emit: ["tick"] }));
19
+ const makeRaw = (tag: string) =>
20
+ Neutron({
21
+ tag,
22
+ props: { isReady: Boolean, tickCount: Number },
23
+ events: { tick: { prefixWithTag: true } },
24
+ })
25
+ .onConnected(onConnectedOriginal)
26
+ .onPropSet("tickCount", onTickSetOriginal)
27
+ .defineMethods({
28
+ bump: ({ tickCount }) => ({ tickCount: (tickCount ?? 0) + 1 }),
29
+ });
30
+
31
+ describe("Neutron: recomposition before define()", () => {
32
+ it("removes and replaces lifecycles by handler reference", async () => {
33
+ const Raw = makeRaw("recompose-a");
34
+ // registry shape the docs describe: [propNames, handler] pairs
35
+ expect(Raw.builtConfig.lifecycles.connected).toEqual([
36
+ [[], onConnectedOriginal],
37
+ ]);
38
+ expect(Raw.builtConfig.lifecycles.propSet).toEqual([
39
+ [["tickCount"], onTickSetOriginal],
40
+ ]);
41
+
42
+ const onConnectedReplacement = vi.fn(() => ({ isReady: false }));
43
+ Raw.offConnected(onConnectedOriginal)
44
+ .onConnected(onConnectedReplacement)
45
+ .offPropSet("tickCount", onTickSetOriginal);
46
+ expect(Raw.builtConfig.lifecycles.connected).toEqual([
47
+ [[], onConnectedReplacement],
48
+ ]);
49
+ expect(Raw.builtConfig.lifecycles.propSet).toEqual([]);
50
+
51
+ Raw.define();
52
+ const el = document.createElement("recompose-a") as any;
53
+ document.body.append(el);
54
+ await wait(1);
55
+ expect(onConnectedOriginal).not.toHaveBeenCalled();
56
+ expect(onConnectedReplacement).toHaveBeenCalledTimes(1);
57
+ expect(el.hasAttribute("is-ready")).toBe(false);
58
+
59
+ const tickListener = vi.fn();
60
+ el.addEventListener("recompose-a-tick", tickListener);
61
+ el.bump();
62
+ await wait(1);
63
+ expect(el.getAttribute("tick-count")).toBe("1");
64
+ expect(onTickSetOriginal).not.toHaveBeenCalled();
65
+ expect(tickListener).not.toHaveBeenCalled();
66
+ el.remove();
67
+ });
68
+
69
+ it("adds lifecycles, methods, and (via compose) props", async () => {
70
+ const Raw = makeRaw("recompose-b");
71
+ const Recomposed = Neutron.compose([
72
+ Raw,
73
+ Neutron({ tag: "recompose-b", props: { extraLabel: String } }),
74
+ ])
75
+ .onPropSet("tickCount", () => ({ extraLabel: "ticked" }))
76
+ .defineMethods({
77
+ reset: () => ({ tickCount: null, extraLabel: null }),
78
+ });
79
+ Recomposed.define();
80
+
81
+ const el = document.createElement("recompose-b") as any;
82
+ document.body.append(el);
83
+ await wait(1);
84
+ // original lifecycles survive alongside the additions
85
+ expect(el.hasAttribute("is-ready")).toBe(true);
86
+ el.bump();
87
+ await wait(1);
88
+ expect(el.getAttribute("tick-count")).toBe("1");
89
+ expect(el.getAttribute("extra-label")).toBe("ticked");
90
+ el.reset();
91
+ await wait(1);
92
+ expect(el.hasAttribute("tick-count")).toBe(false);
93
+ expect(el.hasAttribute("extra-label")).toBe(false);
94
+ // compose deep-clones: the raw builder is untouched
95
+ expect(Raw.builtConfig.props.extraLabel).toBeUndefined();
96
+ expect(Raw.builtConfig.methods.map(([name]) => name)).toEqual(["bump"]);
97
+ el.remove();
98
+ });
99
+
100
+ it("registers under another tag but keeps the configured event prefix", async () => {
101
+ const Raw = makeRaw("recompose-c");
102
+ Raw.define("recompose-c-custom");
103
+ expect(customElements.get("recompose-c")).toBeUndefined();
104
+
105
+ const el = document.createElement("recompose-c-custom") as any;
106
+ document.body.append(el);
107
+ await wait(1);
108
+ const tickListener = vi.fn();
109
+ el.addEventListener("recompose-c-tick", tickListener);
110
+ el.bump();
111
+ await wait(1);
112
+ expect(tickListener).toHaveBeenCalledTimes(1);
113
+ el.remove();
114
+ });
115
+
116
+ it("ignores edits made after define()", async () => {
117
+ const Raw = makeRaw("recompose-d");
118
+ Raw.define();
119
+ const late = vi.fn(() => ({ isReady: false }));
120
+ Raw.onConnected(late);
121
+
122
+ const el = document.createElement("recompose-d") as any;
123
+ document.body.append(el);
124
+ await wait(1);
125
+ expect(late).not.toHaveBeenCalled();
126
+ expect(el.hasAttribute("is-ready")).toBe(true);
127
+ el.remove();
128
+ });
129
+ });
@@ -0,0 +1,75 @@
1
+ import * as utils from "../../src/utils";
2
+ import { describe, expect, it } from "@excom/heft-rig/node_modules/vitest";
3
+
4
+ describe("utils", () => {
5
+ it("isBuiltInElement", () => {
6
+ const el = document.createElement("div");
7
+ expect(utils.isBuiltInElement(el)).to.be.true;
8
+ const el2 = document.createElement("c-e");
9
+ expect(utils.isBuiltInElement(el2)).to.be.false;
10
+ });
11
+
12
+ it("effector", () => {
13
+ const div = document.createElement("div");
14
+ const mutateDiv = utils
15
+ .effector((_, param) => ({
16
+ textContent: "Hello World",
17
+ style: { color: "red" },
18
+ returns: "YES",
19
+ title: param,
20
+ }))
21
+ .bind(div);
22
+ expect(mutateDiv("NEW_TITLE")).to.equal("YES");
23
+ expect(div.textContent).to.equal("Hello World");
24
+ expect(div.style.color).to.equal("red");
25
+ expect(div.title).to.equal("NEW_TITLE");
26
+
27
+ const mutateDiv2 = utils
28
+ .effector(() => [
29
+ { autofocus: true },
30
+ {
31
+ textContent: "Hello!",
32
+ style: { color: "blue" },
33
+ returns: "PERHAPS",
34
+ },
35
+ {
36
+ id: "my-id",
37
+ },
38
+ { id: "other-id" },
39
+ {
40
+ title: "my-title",
41
+ },
42
+ ])
43
+ .bind(div);
44
+ expect(mutateDiv2()).to.equal("PERHAPS");
45
+ expect(div.autofocus).to.be.true;
46
+ expect(div.textContent).to.equal("Hello!");
47
+ expect(div.style.color).to.equal("blue");
48
+ expect(div.id).to.equal("other-id");
49
+ expect(div.title).to.equal("my-title");
50
+ const mutateDiv3 = utils
51
+ .effector(() => [
52
+ {
53
+ textContent: "World!",
54
+ style: { color: "green" },
55
+ returns: "NO",
56
+ },
57
+ { autofocus: false },
58
+ {
59
+ title: "z-title",
60
+ },
61
+ { id: "y-id" },
62
+ {
63
+ id: "x-id",
64
+ },
65
+ ])
66
+ .bind(div);
67
+
68
+ expect(mutateDiv3()).to.equal("NO");
69
+ expect(div.autofocus).to.be.false;
70
+ expect(div.textContent).to.equal("World!");
71
+ expect(div.style.color).to.equal("green");
72
+ expect(div.id).to.equal("x-id");
73
+ expect(div.title).to.equal("z-title");
74
+ });
75
+ });
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
+ }