@alloy-js/core 0.21.0-dev.1 → 0.21.0-dev.13

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 (99) hide show
  1. package/dist/src/binder.d.ts +3 -3
  2. package/dist/src/binder.d.ts.map +1 -1
  3. package/dist/src/binder.js +18 -4
  4. package/dist/src/binder.js.map +1 -1
  5. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  6. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  7. package/dist/src/index.d.ts +1 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +1 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/library-symbol-reference.d.ts +8 -0
  12. package/dist/src/library-symbol-reference.d.ts.map +1 -0
  13. package/dist/src/library-symbol-reference.js +5 -0
  14. package/dist/src/library-symbol-reference.js.map +1 -0
  15. package/dist/src/pretty-string/pretty-string.d.ts +47 -0
  16. package/dist/src/pretty-string/pretty-string.d.ts.map +1 -0
  17. package/dist/src/pretty-string/pretty-string.js +100 -0
  18. package/dist/src/pretty-string/pretty-string.js.map +1 -0
  19. package/dist/src/pretty-string/pretty-string.test.d.ts +2 -0
  20. package/dist/src/pretty-string/pretty-string.test.d.ts.map +1 -0
  21. package/dist/src/pretty-string/pretty-string.test.js +38 -0
  22. package/dist/src/pretty-string/pretty-string.test.js.map +1 -0
  23. package/dist/src/reactivity.d.ts.map +1 -1
  24. package/dist/src/reactivity.js +4 -1
  25. package/dist/src/reactivity.js.map +1 -1
  26. package/dist/src/refkey.d.ts +12 -8
  27. package/dist/src/refkey.d.ts.map +1 -1
  28. package/dist/src/refkey.js +41 -12
  29. package/dist/src/refkey.js.map +1 -1
  30. package/dist/src/render.d.ts.map +1 -1
  31. package/dist/src/render.js +13 -4
  32. package/dist/src/render.js.map +1 -1
  33. package/dist/src/runtime/component.d.ts +22 -2
  34. package/dist/src/runtime/component.d.ts.map +1 -1
  35. package/dist/src/runtime/component.js +18 -0
  36. package/dist/src/runtime/component.js.map +1 -1
  37. package/dist/src/scheduler.d.ts +4 -4
  38. package/dist/src/scheduler.d.ts.map +1 -1
  39. package/dist/src/scheduler.js +10 -5
  40. package/dist/src/scheduler.js.map +1 -1
  41. package/dist/src/symbols/output-scope.js +4 -2
  42. package/dist/src/symbols/output-scope.js.map +1 -1
  43. package/dist/src/symbols/output-symbol.d.ts +9 -0
  44. package/dist/src/symbols/output-symbol.d.ts.map +1 -1
  45. package/dist/src/symbols/output-symbol.js +30 -0
  46. package/dist/src/symbols/output-symbol.js.map +1 -1
  47. package/dist/src/tracer.d.ts.map +1 -1
  48. package/dist/src/tracer.js +4 -4
  49. package/dist/src/tracer.js.map +1 -1
  50. package/dist/src/utils.d.ts +12 -0
  51. package/dist/src/utils.d.ts.map +1 -1
  52. package/dist/src/utils.js +15 -3
  53. package/dist/src/utils.js.map +1 -1
  54. package/dist/test/reactivity/circular-reactives.test.js +18 -0
  55. package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
  56. package/dist/test/refkey.test.js +11 -1
  57. package/dist/test/refkey.test.js.map +1 -1
  58. package/dist/test/rendering/basic.test.js +22 -0
  59. package/dist/test/rendering/basic.test.js.map +1 -1
  60. package/dist/test/symbols/output-scope.test.js +4 -3
  61. package/dist/test/symbols/output-scope.test.js.map +1 -1
  62. package/dist/test/symbols/resolution.test.js +29 -1
  63. package/dist/test/symbols/resolution.test.js.map +1 -1
  64. package/dist/test/utils.test.js +13 -0
  65. package/dist/test/utils.test.js.map +1 -1
  66. package/dist/testing/create-test-wrapper.d.ts +22 -0
  67. package/dist/testing/create-test-wrapper.d.ts.map +1 -0
  68. package/dist/testing/create-test-wrapper.js +60 -0
  69. package/dist/testing/create-test-wrapper.js.map +1 -0
  70. package/dist/testing/index.d.ts +1 -0
  71. package/dist/testing/index.d.ts.map +1 -1
  72. package/dist/testing/index.js +1 -0
  73. package/dist/testing/index.js.map +1 -1
  74. package/dist/tsconfig.tsbuildinfo +1 -1
  75. package/package.json +1 -1
  76. package/src/binder.ts +34 -6
  77. package/src/index.ts +1 -0
  78. package/src/library-symbol-reference.ts +20 -0
  79. package/src/pretty-string/pretty-string.test.ts +47 -0
  80. package/src/pretty-string/pretty-string.ts +130 -0
  81. package/src/reactivity.ts +4 -1
  82. package/src/refkey.ts +68 -26
  83. package/src/render.ts +14 -3
  84. package/src/runtime/component.ts +33 -1
  85. package/src/scheduler.ts +12 -11
  86. package/src/symbols/output-scope.ts +4 -4
  87. package/src/symbols/output-symbol.ts +40 -0
  88. package/src/tracer.ts +5 -8
  89. package/src/utils.tsx +25 -4
  90. package/temp/api.json +854 -92
  91. package/test/reactivity/circular-reactives.test.tsx +20 -0
  92. package/test/refkey.test.ts +12 -1
  93. package/test/rendering/basic.test.tsx +35 -1
  94. package/test/symbols/output-scope.test.ts +4 -4
  95. package/test/symbols/resolution.test.ts +42 -1
  96. package/test/utils.test.tsx +18 -0
  97. package/testing/create-test-wrapper.tsx +70 -0
  98. package/testing/index.ts +1 -0
  99. package/tsconfig.json +1 -0
@@ -30,3 +30,23 @@ it("it should work with circular reactives", () => {
30
30
  item 1
31
31
  `);
32
32
  });
33
+
34
+ it("should work with immediately recursive reactives", () => {
35
+ const items: Set<string> = shallowReactive(new Set());
36
+ const template = (
37
+ <>
38
+ <For each={items.values()}>
39
+ {(item) => {
40
+ items.add("item 1");
41
+ return item;
42
+ }}
43
+ </For>
44
+ </>
45
+ );
46
+ const tree = renderTree(template);
47
+ items.add("item start");
48
+ expect(printTree(tree)).toBe(d`
49
+ item start
50
+ item 1
51
+ `);
52
+ });
@@ -1,5 +1,5 @@
1
1
  import { expect, it } from "vitest";
2
- import { refkey } from "../src/refkey.js";
2
+ import { refkey, REFKEYABLE, Refkeyable } from "../src/refkey.js";
3
3
 
4
4
  it("is stable when called with same values", () => {
5
5
  const obj = {};
@@ -30,3 +30,14 @@ it("can be called with no args and returns a fresh key", () => {
30
30
  const key2 = refkey();
31
31
  expect(key1).not.toBe(key2);
32
32
  });
33
+
34
+ it("unwraps refkeyables", () => {
35
+ const obj = {};
36
+ const rk1 = refkey(obj);
37
+ const refkeyable: Refkeyable = {
38
+ [REFKEYABLE]() {
39
+ return rk1;
40
+ },
41
+ };
42
+ expect(refkey(refkeyable)).toBe(rk1);
43
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { Children } from "../../src/runtime/component.js";
2
+ import { Children, RENDERABLE } from "../../src/runtime/component.js";
3
3
  import "../../testing/extend-expect.js";
4
4
  describe("string nodes", () => {
5
5
  it("renders string nodes with substitutions", () => {
@@ -49,6 +49,40 @@ describe("component nodes", () => {
49
49
  </>,
50
50
  ).toRenderTo("Str Str");
51
51
  });
52
+
53
+ it("renders custom elements", () => {
54
+ const customElement = {
55
+ [RENDERABLE]() {
56
+ return (
57
+ <>
58
+ <Str /> <Str />
59
+ </>
60
+ );
61
+ },
62
+ };
63
+
64
+ expect(customElement).toRenderTo("Str Str");
65
+ });
66
+
67
+ it("renders nested custom elements", () => {
68
+ const e1 = {
69
+ [RENDERABLE]() {
70
+ return <Str />;
71
+ },
72
+ };
73
+
74
+ const e2 = {
75
+ [RENDERABLE]() {
76
+ return (
77
+ <>
78
+ {e1} {e1}
79
+ </>
80
+ );
81
+ },
82
+ };
83
+
84
+ expect(e2).toRenderTo("Str Str");
85
+ });
52
86
  });
53
87
 
54
88
  describe("memo nodes", () => {
@@ -1,6 +1,6 @@
1
1
  import { reactive, watch } from "@vue/reactivity";
2
2
  import { describe, expect, it, vi } from "vitest";
3
- import { Refkey } from "../../src/refkey.js";
3
+ import { refkey } from "../../src/refkey.js";
4
4
  import { flushJobs } from "../../src/scheduler.js";
5
5
  import { BasicScope } from "../../src/symbols/basic-scope.js";
6
6
  import { SymbolTable } from "../../src/symbols/symbol-table.js";
@@ -168,9 +168,9 @@ describe("OutputScope#symbolsByRefkey", () => {
168
168
 
169
169
  // Use the refkey function to create refkeys
170
170
  // This is based on how refkey is being imported in binder.ts
171
- const key1 = "key1" as unknown as Refkey;
172
- const key2a = "key2a" as unknown as Refkey;
173
- const key2b = "key2b" as unknown as Refkey;
171
+ const key1 = refkey();
172
+ const key2a = refkey();
173
+ const key2b = refkey();
174
174
 
175
175
  // Create a symbol with a refkey
176
176
  const [sym1] = createSymbol("sym1", scope, {
@@ -447,6 +447,47 @@ describe("resolving type members by refkey", () => {
447
447
  expect(result.memberPath).toEqual([staticProp]);
448
448
  });
449
449
 
450
+ it("string member", () => {
451
+ const globalScope = createScope("global");
452
+ const [typeSymbol, typeKey] = createSymbol("MyType", globalScope);
453
+ const [staticProp] = createSymbol("staticProp", typeSymbol.staticMembers);
454
+
455
+ // resolve a member of type
456
+ const result = binder.resolveDeclarationByKey(
457
+ globalScope,
458
+ memberRefkey(typeKey, "staticProp"),
459
+ ).value!;
460
+
461
+ expect(result.symbol).toBe(staticProp);
462
+ expect(result.lexicalDeclaration).toBe(typeSymbol);
463
+ expect(result.memberPath).toEqual([staticProp]);
464
+ });
465
+
466
+ it("string member when member symbol changes", async () => {
467
+ const globalScope = createScope("global");
468
+ const [typeSymbol, typeKey] = createSymbol("MyType", globalScope);
469
+ const [staticProp] = createSymbol("staticProp", typeSymbol.staticMembers);
470
+
471
+ // resolve a member of type
472
+ const result = binder.resolveDeclarationByKey(
473
+ globalScope,
474
+ memberRefkey(typeKey, "staticProp"),
475
+ );
476
+
477
+ expect(result.value!.symbol).toBe(staticProp);
478
+ expect(result.value!.lexicalDeclaration).toBe(typeSymbol);
479
+ expect(result.value!.memberPath).toEqual([staticProp]);
480
+
481
+ staticProp.delete();
482
+
483
+ expect(result.value).toBe(undefined);
484
+
485
+ const [staticProp2] = createSymbol("staticProp", typeSymbol.staticMembers);
486
+ expect(result.value!.symbol).toBe(staticProp2);
487
+ expect(result.value!.lexicalDeclaration).toBe(typeSymbol);
488
+ expect(result.value!.memberPath).toEqual([staticProp2]);
489
+ });
490
+
450
491
  it("nested member", () => {
451
492
  const globalScope = createScope("global");
452
493
  const [typeSymbol, typeKey] = createSymbol("MyType", globalScope);
@@ -472,7 +513,7 @@ describe("resolving type members by refkey", () => {
472
513
  // resolve from a member refkey
473
514
  const result2 = binder.resolveDeclarationByKey(
474
515
  globalScope,
475
- memberRefkey(memberRefkey(typeKey, staticPropKey), nestedKey),
516
+ memberRefkey(typeKey, staticPropKey, nestedKey),
476
517
  ).value!;
477
518
 
478
519
  expect(result2.symbol).toBe(nestedProp);
@@ -32,6 +32,24 @@ describe("mapJoin", () => {
32
32
  `);
33
33
  });
34
34
 
35
+ it("can map a set", () => {
36
+ const set = new Set(["hi", "bye"]);
37
+
38
+ function Foo(props: { value: string }) {
39
+ return <>Value: {props.value}</>;
40
+ }
41
+
42
+ const joined = mapJoin(
43
+ () => set,
44
+ (value) => <Foo value={value} />,
45
+ );
46
+
47
+ expect(joined()).toRenderTo(`
48
+ Value: hi
49
+ Value: bye
50
+ `);
51
+ });
52
+
35
53
  it("can map an array", () => {
36
54
  const arr = [1, 2];
37
55
 
@@ -0,0 +1,70 @@
1
+ import {
2
+ Children,
3
+ Declaration,
4
+ For,
5
+ Namekey,
6
+ namekey,
7
+ Output,
8
+ OutputSymbol,
9
+ shallowReactive,
10
+ } from "@alloy-js/core";
11
+
12
+ export interface TestWrapper {
13
+ Wrapper: (props: { children: Children }) => Children;
14
+ defkey: (name: string) => Namekey;
15
+ }
16
+
17
+ /**
18
+ * Generic test wrapper creator.
19
+ */
20
+ export function createTestWrapper<
21
+ SymbolT extends OutputSymbol,
22
+ ScopeT extends { spaces: any },
23
+ >(opts: {
24
+ filePath: string;
25
+ useScope: () => ScopeT | undefined;
26
+ makeSymbol: (nk: Namekey, scope: ScopeT) => SymbolT;
27
+ SourceFile: (props: { path: string; children: Children }) => any;
28
+ }): TestWrapper {
29
+ const seen = shallowReactive(new Map<string, Namekey>());
30
+ const created = new Map<Namekey, SymbolT>();
31
+
32
+ function defkey(name: string): Namekey {
33
+ const existing = seen.get(name);
34
+ if (existing) return existing;
35
+ const nk = namekey(name, {
36
+ ignoreNamePolicy: true,
37
+ ignoreNameConflict: true,
38
+ });
39
+ seen.set(name, nk);
40
+ return nk;
41
+ }
42
+
43
+ function createSymbol(nk: Namekey) {
44
+ const existing = created.get(nk);
45
+ if (existing) return existing;
46
+ const scope = opts.useScope();
47
+ if (!scope) {
48
+ throw new Error(`No SourceFile scope when declaring symbol: ${nk.name}`);
49
+ }
50
+ const sym = opts.makeSymbol(nk, scope);
51
+ created.set(nk, sym);
52
+ return sym;
53
+ }
54
+
55
+ function Wrapper(props: { children: Children }) {
56
+ const SF = opts.SourceFile;
57
+ return (
58
+ <Output>
59
+ <SF path={opts.filePath}>
60
+ <For each={[...seen.values()]} joiner="">
61
+ {(nk) => <Declaration symbol={createSymbol(nk)} />}
62
+ </For>
63
+ {props.children}
64
+ </SF>
65
+ </Output>
66
+ );
67
+ }
68
+
69
+ return { Wrapper, defkey } as const;
70
+ }
package/testing/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import "./extend-expect.js";
2
+ export * from "./create-test-wrapper.jsx";
2
3
  export * from "./render.js";
package/tsconfig.json CHANGED
@@ -11,6 +11,7 @@
11
11
  "test/**/*.ts",
12
12
  "test/**/*.tsx",
13
13
  "testing/**/*.ts",
14
+ "testing/**/*.tsx",
14
15
  "testing/**/*.d.ts",
15
16
  "testing/extend-expect.test.tsx"
16
17
  ],