@alloy-js/core 0.16.0 → 0.18.0-dev.2

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 (249) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/binder.d.ts +19 -235
  3. package/dist/src/binder.d.ts.map +1 -1
  4. package/dist/src/binder.js +85 -386
  5. package/dist/src/code.d.ts +1 -1
  6. package/dist/src/code.d.ts.map +1 -1
  7. package/dist/src/components/Block.d.ts +1 -1
  8. package/dist/src/components/Block.d.ts.map +1 -1
  9. package/dist/src/components/Block.js +3 -1
  10. package/dist/src/components/Declaration.d.ts +2 -2
  11. package/dist/src/components/Declaration.d.ts.map +1 -1
  12. package/dist/src/components/Declaration.js +6 -5
  13. package/dist/src/components/For.d.ts +1 -1
  14. package/dist/src/components/For.d.ts.map +1 -1
  15. package/dist/src/components/For.js +1 -1
  16. package/dist/src/components/Indent.d.ts +1 -1
  17. package/dist/src/components/Indent.d.ts.map +1 -1
  18. package/dist/src/components/List.d.ts +1 -1
  19. package/dist/src/components/List.d.ts.map +1 -1
  20. package/dist/src/components/List.js +3 -1
  21. package/dist/src/components/MemberDeclaration.d.ts +3 -3
  22. package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
  23. package/dist/src/components/MemberDeclaration.js +4 -4
  24. package/dist/src/components/MemberScope.d.ts +2 -2
  25. package/dist/src/components/MemberScope.d.ts.map +1 -1
  26. package/dist/src/components/MemberScope.js +0 -2
  27. package/dist/src/components/Output.d.ts +1 -1
  28. package/dist/src/components/Output.d.ts.map +1 -1
  29. package/dist/src/components/Output.js +1 -1
  30. package/dist/src/components/Prose.d.ts +1 -1
  31. package/dist/src/components/Prose.d.ts.map +1 -1
  32. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  33. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  34. package/dist/src/components/Scope.d.ts +2 -2
  35. package/dist/src/components/Scope.d.ts.map +1 -1
  36. package/dist/src/components/Scope.js +3 -6
  37. package/dist/src/components/Show.d.ts +1 -1
  38. package/dist/src/components/Show.d.ts.map +1 -1
  39. package/dist/src/components/SourceDirectory.d.ts +1 -1
  40. package/dist/src/components/SourceDirectory.d.ts.map +1 -1
  41. package/dist/src/components/SourceDirectory.js +1 -1
  42. package/dist/src/components/SourceFile.d.ts +1 -1
  43. package/dist/src/components/SourceFile.d.ts.map +1 -1
  44. package/dist/src/components/SourceFile.js +1 -1
  45. package/dist/src/components/StatementList.d.ts +1 -1
  46. package/dist/src/components/StatementList.d.ts.map +1 -1
  47. package/dist/src/components/StatementList.js +1 -1
  48. package/dist/src/components/Switch.d.ts +2 -2
  49. package/dist/src/components/Switch.d.ts.map +1 -1
  50. package/dist/src/components/Switch.js +2 -1
  51. package/dist/src/components/Wrap.d.ts +1 -1
  52. package/dist/src/components/Wrap.d.ts.map +1 -1
  53. package/dist/src/context/assignment.d.ts +1 -1
  54. package/dist/src/context/assignment.d.ts.map +1 -1
  55. package/dist/src/context/binder.d.ts +3 -3
  56. package/dist/src/context/binder.d.ts.map +1 -1
  57. package/dist/src/context/declaration.d.ts +1 -1
  58. package/dist/src/context/declaration.d.ts.map +1 -1
  59. package/dist/src/context/member-declaration.d.ts +1 -1
  60. package/dist/src/context/member-declaration.d.ts.map +1 -1
  61. package/dist/src/context/member-declaration.js +0 -1
  62. package/dist/src/context/member-scope.d.ts +1 -1
  63. package/dist/src/context/member-scope.d.ts.map +1 -1
  64. package/dist/src/context/name-policy.d.ts +1 -1
  65. package/dist/src/context/name-policy.d.ts.map +1 -1
  66. package/dist/src/context/scope.d.ts +1 -1
  67. package/dist/src/context/scope.d.ts.map +1 -1
  68. package/dist/src/context/source-directory.d.ts +1 -1
  69. package/dist/src/context/source-directory.d.ts.map +1 -1
  70. package/dist/src/context/source-file.d.ts +2 -2
  71. package/dist/src/context/source-file.d.ts.map +1 -1
  72. package/dist/src/context.d.ts +2 -2
  73. package/dist/src/context.d.ts.map +1 -1
  74. package/dist/src/context.js +1 -1
  75. package/dist/src/debug.d.ts +1 -0
  76. package/dist/src/debug.d.ts.map +1 -1
  77. package/dist/src/debug.js +4 -1
  78. package/dist/src/index.d.ts +8 -2
  79. package/dist/src/index.d.ts.map +1 -1
  80. package/dist/src/index.js +8 -2
  81. package/dist/src/jsx-runtime.d.ts +4 -272
  82. package/dist/src/jsx-runtime.d.ts.map +1 -1
  83. package/dist/src/jsx-runtime.js +3 -315
  84. package/dist/src/props-combinators.d.ts +19 -0
  85. package/dist/src/props-combinators.d.ts.map +1 -0
  86. package/dist/src/props-combinators.js +108 -0
  87. package/dist/src/reactive-union-set.d.ts +29 -0
  88. package/dist/src/reactive-union-set.d.ts.map +1 -0
  89. package/dist/src/reactive-union-set.js +183 -0
  90. package/dist/src/reactivity.d.ts +75 -0
  91. package/dist/src/reactivity.d.ts.map +1 -0
  92. package/dist/src/reactivity.js +141 -0
  93. package/dist/src/refkey.d.ts +36 -0
  94. package/dist/src/refkey.d.ts.map +1 -1
  95. package/dist/src/refkey.js +40 -0
  96. package/dist/src/render.d.ts +5 -1
  97. package/dist/src/render.d.ts.map +1 -1
  98. package/dist/src/render.js +68 -15
  99. package/dist/src/runtime/component.d.ts +24 -0
  100. package/dist/src/runtime/component.d.ts.map +1 -0
  101. package/dist/src/runtime/component.js +19 -0
  102. package/dist/src/runtime/intrinsic.d.ts +168 -0
  103. package/dist/src/runtime/intrinsic.d.ts.map +1 -0
  104. package/dist/src/runtime/intrinsic.js +11 -0
  105. package/dist/src/scheduler.d.ts +2 -2
  106. package/dist/src/scheduler.d.ts.map +1 -1
  107. package/dist/src/scheduler.js +27 -6
  108. package/dist/src/slot.d.ts +2 -2
  109. package/dist/src/slot.d.ts.map +1 -1
  110. package/dist/src/slot.js +1 -1
  111. package/dist/src/stc.d.ts +1 -1
  112. package/dist/src/stc.d.ts.map +1 -1
  113. package/dist/src/sti.d.ts +7 -6
  114. package/dist/src/sti.d.ts.map +1 -1
  115. package/dist/src/sti.js +1 -1
  116. package/dist/src/symbols/flags.d.ts +70 -0
  117. package/dist/src/symbols/flags.d.ts.map +1 -0
  118. package/dist/src/symbols/flags.js +72 -0
  119. package/dist/src/symbols/index.d.ts +7 -0
  120. package/dist/src/symbols/index.d.ts.map +1 -0
  121. package/dist/src/symbols/index.js +6 -0
  122. package/dist/src/symbols/output-scope.d.ts +94 -0
  123. package/dist/src/symbols/output-scope.d.ts.map +1 -0
  124. package/dist/src/symbols/output-scope.js +222 -0
  125. package/dist/src/symbols/output-symbol.d.ts +89 -0
  126. package/dist/src/symbols/output-symbol.d.ts.map +1 -0
  127. package/dist/src/symbols/output-symbol.js +333 -0
  128. package/dist/src/symbols/symbol-flow.d.ts +13 -0
  129. package/dist/src/symbols/symbol-flow.d.ts.map +1 -0
  130. package/dist/src/symbols/symbol-flow.js +74 -0
  131. package/dist/src/symbols/symbol-slot.d.ts +12 -0
  132. package/dist/src/symbols/symbol-slot.d.ts.map +1 -0
  133. package/dist/src/symbols/symbol-slot.js +36 -0
  134. package/dist/src/symbols/symbol-table.d.ts +14 -0
  135. package/dist/src/symbols/symbol-table.d.ts.map +1 -0
  136. package/dist/src/symbols/symbol-table.js +42 -0
  137. package/dist/src/tap.d.ts +3 -2
  138. package/dist/src/tap.d.ts.map +1 -1
  139. package/dist/src/tracer.d.ts +238 -0
  140. package/dist/src/tracer.d.ts.map +1 -0
  141. package/dist/src/tracer.js +496 -0
  142. package/dist/src/tsdoc-metadata.json +1 -1
  143. package/dist/src/utils.d.ts +4 -3
  144. package/dist/src/utils.d.ts.map +1 -1
  145. package/dist/src/utils.js +2 -1
  146. package/dist/test/components/slot.test.js +5 -7
  147. package/dist/test/props-with-defaults.test.js +1 -1
  148. package/dist/test/reactive-union-set.test.d.ts +2 -0
  149. package/dist/test/reactive-union-set.test.d.ts.map +1 -0
  150. package/dist/test/reactive-union-set.test.js +170 -0
  151. package/dist/test/reactivity/cleanup.test.js +2 -1
  152. package/dist/test/reactivity/memo.test.js +1 -1
  153. package/dist/test/reactivity/untrack.test.js +1 -1
  154. package/dist/test/rendering/memoization.test.js +2 -1
  155. package/dist/test/split-props.test.js +1 -1
  156. package/dist/test/symbols/output-scope.test.d.ts +2 -0
  157. package/dist/test/symbols/output-scope.test.d.ts.map +1 -0
  158. package/dist/test/symbols/output-scope.test.js +343 -0
  159. package/dist/test/symbols/output-symbol.test.d.ts +2 -0
  160. package/dist/test/symbols/output-symbol.test.d.ts.map +1 -0
  161. package/dist/test/symbols/output-symbol.test.js +447 -0
  162. package/dist/test/symbols/resolution.test.d.ts +2 -0
  163. package/dist/test/symbols/resolution.test.d.ts.map +1 -0
  164. package/dist/test/symbols/resolution.test.js +141 -0
  165. package/dist/test/symbols/utils.d.ts +25 -0
  166. package/dist/test/symbols/utils.d.ts.map +1 -0
  167. package/dist/test/symbols/utils.js +47 -0
  168. package/dist/testing/extend-expect.d.ts +15 -0
  169. package/dist/testing/extend-expect.d.ts.map +1 -1
  170. package/dist/testing/extend-expect.js +2 -1
  171. package/dist/testing/render.d.ts +1 -1
  172. package/dist/testing/render.d.ts.map +1 -1
  173. package/dist/tsconfig.tsbuildinfo +1 -1
  174. package/package.json +28 -24
  175. package/src/binder.ts +146 -672
  176. package/src/code.ts +1 -1
  177. package/src/components/Block.tsx +4 -1
  178. package/src/components/Declaration.tsx +8 -7
  179. package/src/components/For.tsx +2 -1
  180. package/src/components/Indent.tsx +1 -1
  181. package/src/components/List.tsx +3 -1
  182. package/src/components/MemberDeclaration.tsx +7 -6
  183. package/src/components/MemberScope.tsx +2 -5
  184. package/src/components/Output.tsx +2 -1
  185. package/src/components/Prose.tsx +1 -1
  186. package/src/components/ReferenceOrContent.tsx +1 -1
  187. package/src/components/Scope.tsx +3 -7
  188. package/src/components/Show.tsx +1 -1
  189. package/src/components/SourceDirectory.tsx +2 -1
  190. package/src/components/SourceFile.tsx +2 -1
  191. package/src/components/StatementList.tsx +2 -1
  192. package/src/components/Switch.tsx +2 -1
  193. package/src/components/Wrap.tsx +1 -1
  194. package/src/context/assignment.ts +1 -1
  195. package/src/context/binder.ts +3 -3
  196. package/src/context/declaration.ts +1 -1
  197. package/src/context/member-declaration.ts +1 -1
  198. package/src/context/member-scope.ts +1 -1
  199. package/src/context/name-policy.ts +1 -1
  200. package/src/context/scope.ts +1 -1
  201. package/src/context/source-directory.ts +1 -1
  202. package/src/context/source-file.ts +2 -2
  203. package/src/context.ts +3 -7
  204. package/src/debug.ts +5 -1
  205. package/src/index.ts +15 -1
  206. package/src/jsx-runtime.ts +15 -674
  207. package/src/props-combinators.ts +148 -0
  208. package/src/reactive-union-set.ts +238 -0
  209. package/src/reactivity.ts +230 -0
  210. package/src/refkey.ts +40 -0
  211. package/src/render.ts +97 -26
  212. package/src/runtime/component.ts +67 -0
  213. package/src/runtime/intrinsic.ts +199 -0
  214. package/src/scheduler.ts +31 -6
  215. package/src/slot.ts +3 -4
  216. package/src/stc.ts +2 -2
  217. package/src/sti.ts +11 -11
  218. package/src/symbols/flags.ts +82 -0
  219. package/src/symbols/index.ts +6 -0
  220. package/src/symbols/output-scope.ts +296 -0
  221. package/src/symbols/output-symbol.ts +459 -0
  222. package/src/symbols/symbol-flow.ts +100 -0
  223. package/src/symbols/symbol-slot.tsx +48 -0
  224. package/src/symbols/symbol-table.ts +72 -0
  225. package/src/tap.ts +3 -2
  226. package/src/tracer.ts +474 -0
  227. package/src/utils.tsx +7 -5
  228. package/temp/api.json +7446 -5133
  229. package/test/components/slot.test.tsx +8 -11
  230. package/test/props-with-defaults.test.ts +1 -1
  231. package/test/reactive-union-set.test.tsx +191 -0
  232. package/test/reactivity/cleanup.test.tsx +2 -1
  233. package/test/reactivity/memo.test.tsx +1 -1
  234. package/test/reactivity/untrack.test.ts +1 -1
  235. package/test/rendering/basic.test.tsx +1 -1
  236. package/test/rendering/memoization.test.tsx +1 -1
  237. package/test/split-props.test.ts +1 -1
  238. package/test/symbols/output-scope.test.ts +300 -0
  239. package/test/symbols/output-symbol.test.ts +456 -0
  240. package/test/symbols/resolution.test.ts +170 -0
  241. package/test/symbols/utils.ts +93 -0
  242. package/test/utils.test.tsx +1 -1
  243. package/testing/extend-expect.ts +16 -0
  244. package/testing/render.ts +1 -2
  245. package/LICENSE +0 -7
  246. package/dist/test/symbols.test.d.ts +0 -2
  247. package/dist/test/symbols.test.d.ts.map +0 -1
  248. package/dist/test/symbols.test.js +0 -884
  249. package/test/symbols.test.ts +0 -1006
@@ -0,0 +1,170 @@
1
+ import { reactive } from "@vue/reactivity";
2
+ import { describe, expect, it } from "vitest";
3
+ import { ReactiveUnionSet } from "../src/reactive-union-set.js";
4
+ import { effect } from "../src/reactivity.js";
5
+ import { flushJobs } from "../src/scheduler.js";
6
+ describe("is reactive", () => {
7
+ it("on size", () => {
8
+ const set = new ReactiveUnionSet();
9
+ let callCount = 0;
10
+ effect(() => {
11
+ callCount++;
12
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
13
+ set.size;
14
+ });
15
+ set.add(1);
16
+ flushJobs();
17
+ expect(callCount).toBe(2);
18
+ });
19
+ it("on iteration", () => {
20
+ const set = new ReactiveUnionSet();
21
+ let callCount = 0;
22
+ effect(() => {
23
+ callCount++;
24
+ for (const _ of set) {
25
+ // do nothing
26
+ }
27
+ });
28
+ set.add(1);
29
+ flushJobs();
30
+ expect(callCount).toBe(2);
31
+ });
32
+ it("on deletion with iteration", () => {
33
+ const set = new ReactiveUnionSet();
34
+ let callCount = 0;
35
+ effect(() => {
36
+ callCount++;
37
+ for (const _ of set) {
38
+ // do nothing
39
+ }
40
+ });
41
+ set.add(1);
42
+ flushJobs();
43
+ expect(callCount).toBe(2);
44
+ set.delete(1);
45
+ flushJobs();
46
+ expect(callCount).toBe(3);
47
+ });
48
+ });
49
+ it("adds items to main set from subset", () => {
50
+ const set = new ReactiveUnionSet();
51
+ const subset1 = reactive(new Set());
52
+ const subset2 = reactive(new Set());
53
+ set.addSubset(subset1);
54
+ set.addSubset(subset2);
55
+ subset1.add(1);
56
+ subset2.add(2);
57
+ flushJobs();
58
+ expect(set.has(1)).toBe(true);
59
+ expect(set.has(2)).toBe(true);
60
+ subset1.delete(1);
61
+ flushJobs();
62
+ expect(set.has(1)).toBe(false);
63
+ });
64
+ it("doesn't remove items that are present in more than one subset", () => {
65
+ const set = new ReactiveUnionSet();
66
+ const subset1 = reactive(new Set());
67
+ const subset2 = reactive(new Set());
68
+ set.addSubset(subset1);
69
+ set.addSubset(subset2);
70
+ subset1.add(1);
71
+ subset2.add(1);
72
+ flushJobs();
73
+ expect(set.has(1)).toBe(true);
74
+ subset1.delete(1);
75
+ flushJobs();
76
+ expect(set.has(1)).toBe(true);
77
+ subset2.delete(1);
78
+ flushJobs();
79
+ expect(set.has(1)).toBe(false);
80
+ });
81
+ it("removes all items when you clear the subset", () => {
82
+ const set = new ReactiveUnionSet();
83
+ const subset1 = reactive(new Set());
84
+ const subset2 = reactive(new Set());
85
+ set.addSubset(subset1);
86
+ set.addSubset(subset2);
87
+ subset1.add(1);
88
+ subset1.add(2);
89
+ subset1.add(3);
90
+ subset2.add(1);
91
+ flushJobs();
92
+ expect(set.size).toBe(3);
93
+ subset1.clear();
94
+ flushJobs();
95
+ expect(set.size).toBe(1);
96
+ });
97
+ describe("indexing", () => {
98
+ it("creates an index of properties", () => {
99
+ const set = new ReactiveUnionSet();
100
+ const index = set.createIndex(item => item.id);
101
+ let callCount = 0;
102
+ effect(() => {
103
+ callCount++;
104
+ index.values();
105
+ });
106
+ const brian = {
107
+ id: 1,
108
+ name: "brian"
109
+ };
110
+ const timothee = {
111
+ id: 2,
112
+ name: "timothee"
113
+ };
114
+ set.add(brian);
115
+ set.add(timothee);
116
+ flushJobs();
117
+ expect(callCount).toBe(2);
118
+ expect(index.get(1)).toEqual(brian);
119
+ expect(index.get(2)).toEqual(timothee);
120
+ set.delete(brian);
121
+ flushJobs();
122
+ expect(callCount).toBe(3);
123
+ expect(index.get(1)).toBeUndefined();
124
+ });
125
+ it("updates the index when the item changeS", () => {
126
+ const set = new ReactiveUnionSet();
127
+ const index = set.createIndex(item => item.id);
128
+ let callCount = 0;
129
+ effect(() => {
130
+ callCount++;
131
+ index.values();
132
+ });
133
+ const brian = reactive({
134
+ id: 1,
135
+ name: "brian"
136
+ });
137
+ set.add(brian);
138
+ flushJobs();
139
+ expect(index.get(1)).toEqual(brian);
140
+ brian.id = 2;
141
+ flushJobs();
142
+ expect(callCount).toBe(3);
143
+ expect(index.get(2)).toEqual(brian);
144
+ });
145
+ });
146
+ describe("derived sets", () => {
147
+ it("creates a derived set", () => {
148
+ const set = new ReactiveUnionSet();
149
+ const derivedSet = set.createDerivedSet(item => item.name);
150
+ const brian = {
151
+ id: 1,
152
+ name: "brian"
153
+ };
154
+ const timothee = {
155
+ id: 2,
156
+ name: "timothee"
157
+ };
158
+ set.add(brian);
159
+ set.add(timothee);
160
+ flushJobs();
161
+ expect(derivedSet.size).toBe(2);
162
+ expect(derivedSet.has("brian")).toBe(true);
163
+ expect(derivedSet.has("timothee")).toBe(true);
164
+ set.delete(brian);
165
+ flushJobs();
166
+ expect(derivedSet.size).toBe(1);
167
+ expect(derivedSet.has("brian")).toBe(false);
168
+ expect(derivedSet.has("timothee")).toBe(true);
169
+ });
170
+ });
@@ -1,6 +1,7 @@
1
- import { effect, memo, onCleanup, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
1
+ import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
2
  import { ref } from "@vue/reactivity";
3
3
  import { describe, expect, it } from "vitest";
4
+ import { effect, memo, onCleanup } from "../../src/reactivity.js";
4
5
  import { renderTree } from "../../src/render.js";
5
6
  import { flushJobs } from "../../src/scheduler.js";
6
7
  describe("memo cleanup", () => {
@@ -1,6 +1,6 @@
1
- import { memo } from "@alloy-js/core/jsx-runtime";
2
1
  import { ref } from "@vue/reactivity";
3
2
  import { expect, it } from "vitest";
3
+ import { memo } from "../../src/reactivity.js";
4
4
  it("doesn't recalculate when dependencies don't change", () => {
5
5
  const signal = ref(0);
6
6
  let callCount = 0;
@@ -1,6 +1,6 @@
1
1
  import { ref } from "@vue/reactivity";
2
2
  import { expect, it } from "vitest";
3
- import { memo, untrack } from "../../src/jsx-runtime.js";
3
+ import { memo, untrack } from "../../src/reactivity.js";
4
4
  import { flushJobs } from "../../src/scheduler.js";
5
5
  it("ignores signals for dependency tracking", () => {
6
6
  const signal = ref(0);
@@ -1,6 +1,7 @@
1
- import { memo, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
1
+ import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
2
  import { ref } from "@vue/reactivity";
3
3
  import { expect, it } from "vitest";
4
+ import { memo } from "../../src/reactivity.js";
4
5
  import { renderTree } from "../../src/render.js";
5
6
  import { flushJobs } from "../../src/scheduler.js";
6
7
  it("memoizes child components", () => {
@@ -1,6 +1,6 @@
1
1
  import { effect, reactive } from "@vue/reactivity";
2
2
  import { expect, it, vi } from "vitest";
3
- import { splitProps } from "../src/jsx-runtime.js";
3
+ import { splitProps } from "../src/props-combinators.js";
4
4
  it("splits regular object props", () => {
5
5
  const props = {
6
6
  a: 1,
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=output-scope.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-scope.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/output-scope.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,343 @@
1
+ import { reactive, watch } from "@vue/reactivity";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { createOutputBinder } from "../../src/binder.js";
4
+ import { flushJobs } from "../../src/scheduler.js";
5
+ import { OutputScopeFlags } from "../../src/symbols/flags.js";
6
+ import { OutputScope } from "../../src/symbols/output-scope.js";
7
+ import { OutputSymbol } from "../../src/symbols/output-symbol.js";
8
+ import { SymbolTable } from "../../src/symbols/symbol-table.js";
9
+ let binder;
10
+ beforeEach(() => {
11
+ binder = createOutputBinder();
12
+ });
13
+ describe("OutputScope constructor", () => {
14
+ it("initializes properties correctly with default options", () => {
15
+ const scope = new OutputScope("testScope", {
16
+ binder
17
+ });
18
+ expect(scope.name).toBe("testScope");
19
+ expect(scope.binder).toBe(binder);
20
+ expect(scope.id).toEqual(expect.any(Number));
21
+ expect(scope.kind).toBe("scope");
22
+ expect(scope.flags).toBe(OutputScopeFlags.None);
23
+ expect(scope.metadata).toEqual({});
24
+ expect(scope.parent).toBe(binder.globalScope);
25
+ expect(scope.owner).toBeUndefined();
26
+ expect(scope.symbols).toBeInstanceOf(SymbolTable);
27
+ expect(scope.symbolNames.size).toBe(0);
28
+ expect(scope.children.size).toBe(0);
29
+ });
30
+ it("initializes properties correctly with custom options", () => {
31
+ const parentScope = new OutputScope("parentScope", {
32
+ binder
33
+ });
34
+ const metadata = {
35
+ foo: "bar"
36
+ };
37
+ const scope = new OutputScope("testScope", {
38
+ binder,
39
+ kind: "namespace",
40
+ metadata,
41
+ parent: parentScope
42
+ });
43
+ expect(scope.name).toBe("testScope");
44
+ expect(scope.kind).toBe("namespace");
45
+ expect(scope.flags).toBe(OutputScopeFlags.None);
46
+ expect(scope.metadata.foo).toBe("bar");
47
+ expect(scope.parent).toBe(parentScope);
48
+ expect(parentScope.children.has(scope)).toBe(true);
49
+ });
50
+ });
51
+ describe("OutputScope reactivity", () => {
52
+ it("is reactive on name", () => {
53
+ const scope = new OutputScope("initialName", {
54
+ binder
55
+ });
56
+ const nameSpy = vi.fn();
57
+ watch(() => scope.name, nameSpy);
58
+ scope.name = "newName";
59
+ flushJobs();
60
+ expect(nameSpy).toHaveBeenCalled();
61
+ expect(scope.name).toBe("newName");
62
+ });
63
+ it("is reactive on flags", () => {
64
+ const scope = new OutputScope("scope", {
65
+ binder
66
+ });
67
+ const flagsSpy = vi.fn();
68
+ watch(() => scope.flags, flagsSpy);
69
+ scope.flags = OutputScopeFlags.InstanceMemberScope;
70
+ flushJobs();
71
+ expect(flagsSpy).toHaveBeenCalled();
72
+ expect(scope.flags).toBe(OutputScopeFlags.InstanceMemberScope);
73
+ });
74
+ it("updates symbolNames when symbols are added", () => {
75
+ const scope = new OutputScope("scope", {
76
+ binder
77
+ });
78
+ const symbolNamesSpy = vi.fn();
79
+ watch(() => scope.symbolNames.size, symbolNamesSpy);
80
+ new OutputSymbol("symbol1", {
81
+ binder,
82
+ scope
83
+ });
84
+ flushJobs();
85
+ expect(symbolNamesSpy).toHaveBeenCalled();
86
+ expect(scope.symbolNames.has("symbol1")).toBe(true);
87
+ });
88
+ it("updates symbolNames when a symbol's name changes", () => {
89
+ const scope = new OutputScope("scope", {
90
+ binder
91
+ });
92
+ const symbol = new OutputSymbol("oldName", {
93
+ binder,
94
+ scope
95
+ });
96
+ flushJobs();
97
+
98
+ // Verify initial state
99
+ expect(scope.symbolNames.has("oldName")).toBe(true);
100
+ expect(scope.symbolNames.has("newName")).toBe(false);
101
+
102
+ // Set up tracking for symbol names
103
+ const symbolNamesTracker = vi.fn();
104
+ watch(() => ({
105
+ hasOld: scope.symbolNames.has("oldName"),
106
+ hasNew: scope.symbolNames.has("newName")
107
+ }), symbolNamesTracker, {
108
+ deep: true
109
+ });
110
+
111
+ // Change the name
112
+ symbol.name = "newName";
113
+ flushJobs();
114
+
115
+ // Verify the changes
116
+ expect(symbolNamesTracker).toHaveBeenCalled();
117
+ expect(scope.symbolNames.has("oldName")).toBe(false);
118
+ expect(scope.symbolNames.has("newName")).toBe(true);
119
+ });
120
+ it("doesn't get wrapped in a reactive proxy", () => {
121
+ const scope = new OutputScope("scope", {
122
+ binder
123
+ });
124
+ const rScope = reactive(scope);
125
+ expect(rScope).toBe(scope);
126
+ });
127
+ });
128
+ describe("OutputScope#symbols", () => {
129
+ it("adds symbols to its collection", () => {
130
+ const scope = new OutputScope("scope", {
131
+ binder
132
+ });
133
+ const sym1 = new OutputSymbol("sym1", {
134
+ binder,
135
+ scope
136
+ });
137
+ const sym2 = new OutputSymbol("sym2", {
138
+ binder,
139
+ scope
140
+ });
141
+ flushJobs();
142
+ expect(scope.symbols.size).toBe(2);
143
+ expect(scope.symbols.has(sym1)).toBe(true);
144
+ expect(scope.symbols.has(sym2)).toBe(true);
145
+ });
146
+ it("resolves symbol name conflicts", () => {
147
+ const scope = new OutputScope("scope", {
148
+ binder
149
+ });
150
+ const s1 = new OutputSymbol("sym", {
151
+ binder,
152
+ scope
153
+ });
154
+ const s2 = new OutputSymbol("sym", {
155
+ binder,
156
+ scope
157
+ });
158
+ const s3 = new OutputSymbol("sym", {
159
+ binder,
160
+ scope
161
+ });
162
+ flushJobs();
163
+ expect(s1.name).toBe("sym");
164
+ expect(s2.name).toBe("sym_2");
165
+ expect(s3.name).toBe("sym_3");
166
+ expect(scope.symbolNames.has("sym")).toBe(true);
167
+ expect(scope.symbolNames.has("sym_2")).toBe(true);
168
+ expect(scope.symbolNames.has("sym_3")).toBe(true);
169
+ });
170
+ it("updates when a symbol is deleted", () => {
171
+ const scope = new OutputScope("scope", {
172
+ binder
173
+ });
174
+ const sym = new OutputSymbol("sym", {
175
+ binder,
176
+ scope
177
+ });
178
+ flushJobs();
179
+ expect(scope.symbols.size).toBe(1);
180
+ expect(scope.symbols.has(sym)).toBe(true);
181
+ expect(scope.symbolNames.has("sym")).toBe(true);
182
+ sym.delete();
183
+ flushJobs();
184
+ expect(scope.symbols.size).toBe(0);
185
+ expect(scope.symbols.has(sym)).toBe(false);
186
+ expect(scope.symbolNames.has("sym")).toBe(false);
187
+ });
188
+ it("updates when a symbol changes scope", () => {
189
+ const scope1 = new OutputScope("scope1", {
190
+ binder
191
+ });
192
+ const scope2 = new OutputScope("scope2", {
193
+ binder
194
+ });
195
+ const sym = new OutputSymbol("sym", {
196
+ binder,
197
+ scope: scope1
198
+ });
199
+ flushJobs();
200
+ expect(scope1.symbols.size).toBe(1);
201
+ expect(scope2.symbols.size).toBe(0);
202
+ sym.scope = scope2;
203
+ flushJobs();
204
+ expect(scope1.symbols.size).toBe(0);
205
+ expect(scope2.symbols.size).toBe(1);
206
+ expect(scope1.symbols.has(sym)).toBe(false);
207
+ expect(scope2.symbols.has(sym)).toBe(true);
208
+ expect(scope1.symbolNames.has("sym")).toBe(false);
209
+ expect(scope2.symbolNames.has("sym")).toBe(true);
210
+ });
211
+ });
212
+ describe("OutputScope#symbolsByRefkey", () => {
213
+ it("maps refkeys to symbols", () => {
214
+ const scope = new OutputScope("scope", {
215
+ binder
216
+ });
217
+
218
+ // Use the refkey function to create refkeys
219
+ // This is based on how refkey is being imported in binder.ts
220
+ const key1 = "key1";
221
+ const key2a = "key2a";
222
+ const key2b = "key2b";
223
+
224
+ // Create a symbol with a refkey
225
+ const sym1 = new OutputSymbol("sym1", {
226
+ binder,
227
+ scope,
228
+ refkeys: [key1]
229
+ });
230
+
231
+ // Create a symbol with multiple refkeys
232
+ const sym2 = new OutputSymbol("sym2", {
233
+ binder,
234
+ scope,
235
+ refkeys: [key2a, key2b]
236
+ });
237
+ flushJobs();
238
+ expect(scope.symbolsByRefkey.get(key1)).toBe(sym1);
239
+ expect(scope.symbolsByRefkey.get(key2a)).toBe(sym2);
240
+ expect(scope.symbolsByRefkey.get(key2b)).toBe(sym2);
241
+ });
242
+ });
243
+ describe("OutputScope#children", () => {
244
+ it("tracks child scopes", () => {
245
+ const parentScope = new OutputScope("parent", {
246
+ binder
247
+ });
248
+ const child1 = new OutputScope("child1", {
249
+ binder,
250
+ parent: parentScope
251
+ });
252
+ const child2 = new OutputScope("child2", {
253
+ binder,
254
+ parent: parentScope
255
+ });
256
+ flushJobs();
257
+ expect(parentScope.children.size).toBe(2);
258
+ expect(parentScope.children.has(child1)).toBe(true);
259
+ expect(parentScope.children.has(child2)).toBe(true);
260
+
261
+ // Check that each child's parent is set correctly
262
+ expect(child1.parent).toBe(parentScope);
263
+ expect(child2.parent).toBe(parentScope);
264
+ });
265
+ });
266
+ describe("OutputScope#clone", () => {
267
+ let originalScope;
268
+ const originalMetadata = {
269
+ data: "original",
270
+ nested: {
271
+ value: 1
272
+ }
273
+ };
274
+ beforeEach(() => {
275
+ const parentScope = new OutputScope("parent", {
276
+ binder
277
+ });
278
+ originalScope = new OutputScope("original", {
279
+ binder: binder,
280
+ kind: "class",
281
+ metadata: {
282
+ ...originalMetadata
283
+ },
284
+ parent: parentScope
285
+ });
286
+
287
+ // Add a symbol and child scope to the original
288
+ new OutputSymbol("symbolInOriginal", {
289
+ binder,
290
+ scope: originalScope
291
+ });
292
+ new OutputScope("childOfOriginal", {
293
+ binder,
294
+ parent: originalScope
295
+ });
296
+ flushJobs();
297
+ });
298
+ it("clones basic properties", () => {
299
+ const newScope = new OutputScope("newScope", {
300
+ binder
301
+ });
302
+ const clonedScope = originalScope.clone({
303
+ parent: newScope
304
+ });
305
+ expect(clonedScope.name).toBe(originalScope.name);
306
+ expect(clonedScope.kind).toBe(originalScope.kind);
307
+ expect(clonedScope.flags).toBe(originalScope.flags);
308
+ expect(clonedScope.id).not.toBe(originalScope.id);
309
+ expect(clonedScope.metadata).toEqual(originalScope.metadata);
310
+ expect(clonedScope.symbols.size).toBe(1);
311
+ expect(clonedScope.children.size).toBe(1);
312
+ });
313
+ it("can override parent in clone options", () => {
314
+ const newParent = new OutputScope("newParent", {
315
+ binder
316
+ });
317
+ const clonedScope = originalScope.clone({
318
+ parent: newParent
319
+ });
320
+ flushJobs();
321
+ expect(clonedScope.parent).toBe(newParent);
322
+ expect(newParent.children.has(clonedScope)).toBe(true);
323
+ });
324
+ it("can override owner in clone options", () => {
325
+ const newOwnerParent = new OutputScope("newOwnerParent", {
326
+ binder
327
+ });
328
+ const newOwner = new OutputSymbol("newOwner", {
329
+ binder,
330
+ scope: newOwnerParent
331
+ });
332
+ const clonedScope = originalScope.clone({
333
+ owner: newOwner
334
+ });
335
+ flushJobs();
336
+ expect(clonedScope.owner).toBe(newOwner);
337
+ });
338
+ it("allows independent changes to clone properties", () => {
339
+ const clonedScope = originalScope.clone();
340
+ clonedScope.name = "clonedName";
341
+ expect(originalScope.name).toBe("original");
342
+ });
343
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=output-symbol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-symbol.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/output-symbol.test.ts"],"names":[],"mappings":""}