@excom/quark 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 (130) hide show
  1. package/.rush/temp/chunked-rush-logs/quark.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/quark.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 +4 -0
  12. package/language.ts +7 -0
  13. package/package.json +45 -0
  14. package/rush-logs/quark.apply-exports.cache.log +1 -0
  15. package/rush-logs/quark.apply-exports.log +1 -0
  16. package/rush-logs/quark.build_package-metas.cache.log +1 -0
  17. package/rush-logs/quark.build_package-metas.log +1 -0
  18. package/src/actions.ts +445 -0
  19. package/src/ast.ts +187 -0
  20. package/src/bindings.ts +115 -0
  21. package/src/builtin-modules.ts +401 -0
  22. package/src/constants.ts +47 -0
  23. package/src/cycle-check.ts +121 -0
  24. package/src/devtools-hook.ts +303 -0
  25. package/src/element-api.ts +109 -0
  26. package/src/evaluator.ts +317 -0
  27. package/src/form-controls.ts +69 -0
  28. package/src/language-tables.ts +137 -0
  29. package/src/language.ts +1225 -0
  30. package/src/observer.ts +110 -0
  31. package/src/paint.ts +305 -0
  32. package/src/properties.ts +818 -0
  33. package/src/props.ts +94 -0
  34. package/src/quark-element.ts +7 -0
  35. package/src/quark-internal.ts +365 -0
  36. package/src/quark.ts +817 -0
  37. package/src/resolvers.ts +867 -0
  38. package/src/rule.ts +800 -0
  39. package/src/scope-id.ts +47 -0
  40. package/src/selector-utils.ts +430 -0
  41. package/src/settle.ts +117 -0
  42. package/src/types.ts +155 -0
  43. package/src/utils.ts +79 -0
  44. package/src/variables.ts +359 -0
  45. package/support/demos/css-variables.html +18 -0
  46. package/support/demos/dispatch.html +20 -0
  47. package/support/demos/events.html +9 -0
  48. package/support/demos/iterate.html +13 -0
  49. package/support/demos/js-api.html +17 -0
  50. package/support/demos/provider-list.html +16 -0
  51. package/support/demos/toggle-content.html +14 -0
  52. package/support/demos/unset.html +12 -0
  53. package/support/demos/view-transition.html +36 -0
  54. package/support/docs/ATTRIBUTES.md +37 -0
  55. package/support/docs/AT_RULES.md +45 -0
  56. package/support/docs/BUILTINS.md +57 -0
  57. package/support/docs/CONTENT.md +40 -0
  58. package/support/docs/CSS_VARIABLES.md +16 -0
  59. package/support/docs/DECLARATIONS.md +26 -0
  60. package/support/docs/DELAY.md +37 -0
  61. package/support/docs/DIAGNOSTICS.md +32 -0
  62. package/support/docs/DISPATCH.md +81 -0
  63. package/support/docs/ELEMENT_PROPERTIES.md +34 -0
  64. package/support/docs/EXPRESSIONS.md +31 -0
  65. package/support/docs/INTERNAL.md +8 -0
  66. package/support/docs/JS_API.md +53 -0
  67. package/support/docs/JS_WRITES.md +36 -0
  68. package/support/docs/LIMITATIONS.md +26 -0
  69. package/support/docs/LOOP_GUARD.md +30 -0
  70. package/support/docs/METHODS.md +43 -0
  71. package/support/docs/MODULES.md +111 -0
  72. package/support/docs/NO_REVERSION.md +18 -0
  73. package/support/docs/ON.md +87 -0
  74. package/support/docs/REACTIVITY.md +24 -0
  75. package/support/docs/README.md +143 -0
  76. package/support/docs/SELECTORS.md +87 -0
  77. package/support/docs/SHEETS.md +67 -0
  78. package/support/docs/SYNTAX.md +36 -0
  79. package/support/docs/USE.md +24 -0
  80. package/support/docs/VALUES.md +27 -0
  81. package/support/docs/VARIABLES.md +47 -0
  82. package/support/docs/VIEW_TRANSITION.md +64 -0
  83. package/support/docs-sections.json +65 -0
  84. package/support/package-meta.json +208 -0
  85. package/support/scripts/build-language-docs.mjs +196 -0
  86. package/support/tests/__snapshots__/css-variables.view.test.ts.snap +23 -0
  87. package/support/tests/__snapshots__/dispatch.view.test.ts.snap +23 -0
  88. package/support/tests/__snapshots__/events.view.test.ts.snap +23 -0
  89. package/support/tests/__snapshots__/iterate.view.test.ts.snap +23 -0
  90. package/support/tests/__snapshots__/js-api.view.test.ts.snap +23 -0
  91. package/support/tests/__snapshots__/provider-list.view.test.ts.snap +23 -0
  92. package/support/tests/__snapshots__/quark-features.test.ts.snap +1079 -0
  93. package/support/tests/__snapshots__/quark-with-providers.test.ts.snap +89 -0
  94. package/support/tests/__snapshots__/quark.test.ts.snap +221 -0
  95. package/support/tests/__snapshots__/selectors.test.ts.snap +133 -0
  96. package/support/tests/__snapshots__/toggle-content.view.test.ts.snap +23 -0
  97. package/support/tests/__snapshots__/unset.view.test.ts.snap +23 -0
  98. package/support/tests/__snapshots__/view-transition.view.test.ts.snap +23 -0
  99. package/support/tests/actions.test.ts +437 -0
  100. package/support/tests/builtin-modules.test.ts +337 -0
  101. package/support/tests/builtins.test.ts +189 -0
  102. package/support/tests/css-variables.view.test.ts +35 -0
  103. package/support/tests/delay.test.ts +244 -0
  104. package/support/tests/devtools-hook.test.ts +496 -0
  105. package/support/tests/diagnostics.test.ts +224 -0
  106. package/support/tests/dispatch.view.test.ts +43 -0
  107. package/support/tests/element-api.test.ts +202 -0
  108. package/support/tests/evaluator.test.ts +237 -0
  109. package/support/tests/events.view.test.ts +40 -0
  110. package/support/tests/form-controls.test.ts +452 -0
  111. package/support/tests/helpers.ts +354 -0
  112. package/support/tests/internals.test.ts +568 -0
  113. package/support/tests/iterate.view.test.ts +40 -0
  114. package/support/tests/js-api.view.test.ts +45 -0
  115. package/support/tests/language-docs.test.ts +147 -0
  116. package/support/tests/lifecycle.test.ts +440 -0
  117. package/support/tests/loop-guard.test.ts +323 -0
  118. package/support/tests/provider-list.view.test.ts +47 -0
  119. package/support/tests/quark-features.test.ts +2887 -0
  120. package/support/tests/quark-with-providers.test.ts +169 -0
  121. package/support/tests/quark.test.ts +359 -0
  122. package/support/tests/resolvers.test.ts +346 -0
  123. package/support/tests/selector-analysis.test.ts +281 -0
  124. package/support/tests/selectors.test.ts +670 -0
  125. package/support/tests/toggle-content.view.test.ts +40 -0
  126. package/support/tests/unset.view.test.ts +42 -0
  127. package/support/tests/view-helpers.ts +81 -0
  128. package/support/tests/view-transition.test.ts +1069 -0
  129. package/support/tests/view-transition.view.test.ts +76 -0
  130. package/tsconfig.json +5 -0
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Renders the language metadata in `src/language.ts` into the generated
4
+ * regions of the doc pages under `support/docs/` (`REGION_FILES` says which
5
+ * page holds which table).
6
+ *
7
+ * node support/scripts/build-language-docs.mjs
8
+ *
9
+ * Regions are fenced by `<!-- generated:<name> -->` / `<!-- /generated -->`
10
+ * markers; everything between them is replaced. `language-docs.test.ts`
11
+ * fails when a page is out of date, so run this after editing the
12
+ * metadata. Plain Node imports the `.ts` module (type stripping); the test
13
+ * imports this file under Vite.
14
+ */
15
+ import { readFile, writeFile } from "node:fs/promises";
16
+ import path from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import { realpathSync } from "node:fs";
19
+ import {
20
+ ALLOWED_METHODS,
21
+ AT_RULES,
22
+ BUILTIN_FUNCTIONS,
23
+ BUILTIN_MODULES,
24
+ COMBINATORS,
25
+ DECLARATION_KINDS,
26
+ PSEUDO_CLASSES,
27
+ VALUE_KEYWORDS,
28
+ } from "../../src/language.ts";
29
+
30
+ const DOCS_DIR = path.resolve(
31
+ path.dirname(fileURLToPath(import.meta.url)),
32
+ "../docs"
33
+ );
34
+
35
+ /** Generated region → the doc page that carries it. */
36
+ export const REGION_FILES = {
37
+ "at-rules": "AT_RULES.md",
38
+ "declaration-kinds": "DECLARATIONS.md",
39
+ "value-keywords": "VALUES.md",
40
+ "builtin-functions": "BUILTINS.md",
41
+ "allowed-methods": "METHODS.md",
42
+ selectors: "SELECTORS.md",
43
+ "builtin-modules": "MODULES.md",
44
+ };
45
+
46
+ const cell = (text) => text.replace(/\|/g, "\\|").replace(/\n/g, " ");
47
+
48
+ const table = (header, rows) =>
49
+ [
50
+ `| ${header.join(" | ")} |`,
51
+ `| ${header.map(() => "---").join(" | ")} |`,
52
+ ...rows.map((row) => `| ${row.map(cell).join(" | ")} |`),
53
+ ].join("\n");
54
+
55
+ const GROUP_TITLES = {
56
+ element: "Element reads",
57
+ loop: "Loop context",
58
+ render: "Rendering (`content`)",
59
+ event: "Event listeners",
60
+ state: "State",
61
+ util: "Utilities",
62
+ debug: "Debugging",
63
+ };
64
+
65
+ const PSEUDO_KIND_TITLES = {
66
+ logical: "Logical",
67
+ relational: "Relational",
68
+ structural: "Structural (sibling position, children)",
69
+ attribute: "Attribute-backed",
70
+ static: "Static",
71
+ };
72
+
73
+ const renderSelectors = () => {
74
+ const unobserved = PSEUDO_CLASSES.filter((p) => p.kind === "unobserved");
75
+ return [
76
+ `**Combinators**\n\n${table(
77
+ ["Combinator", "Observed"],
78
+ COMBINATORS.map((c) => [`\`${c.syntax}\``, c.description])
79
+ )}`,
80
+ ...Object.entries(PSEUDO_KIND_TITLES).map(([kind, title]) => {
81
+ const rows = PSEUDO_CLASSES.filter((p) => p.kind === kind);
82
+ return `**${title}**\n\n${table(
83
+ ["Pseudo-class", "Observed"],
84
+ rows.map((p) => [`\`${p.syntax}\``, p.description])
85
+ )}`;
86
+ }),
87
+ `**Not observed** — ${unobserved
88
+ .map((p) => `\`${p.syntax}\``)
89
+ .join(
90
+ ", "
91
+ )}: ${unobserved[0].description} Any pseudo-class not listed above is treated the same way.`,
92
+ ].join("\n\n");
93
+ };
94
+
95
+ /** Region name → rendered markdown. */
96
+ export const renderLanguageDocs = () => ({
97
+ "at-rules": table(
98
+ ["At-rule", "Effect"],
99
+ AT_RULES.map((a) => [`\`${a.syntax}\``, a.description])
100
+ ),
101
+ "value-keywords": table(
102
+ ["Keyword", "Meaning"],
103
+ VALUE_KEYWORDS.map((k) => [`\`${k.name}\``, k.description])
104
+ ),
105
+ "declaration-kinds": table(
106
+ ["Key", "Effect", "Accepts"],
107
+ DECLARATION_KINDS.map((d) => [`\`${d.key}\``, d.description, d.accepts])
108
+ ),
109
+ "builtin-functions": Object.entries(GROUP_TITLES)
110
+ .map(([group, title]) => {
111
+ const rows = BUILTIN_FUNCTIONS.filter((f) => f.group === group);
112
+ if (!rows.length) return null;
113
+ return `**${title}**\n\n${table(
114
+ ["Name", "Description"],
115
+ rows.map((f) => [`\`${f.signature}\``, f.description])
116
+ )}`;
117
+ })
118
+ .filter(Boolean)
119
+ .join("\n\n"),
120
+ "builtin-modules": BUILTIN_MODULES.map(
121
+ (m) =>
122
+ `**\`quark:${m.name}\`** — ${m.description}\n\n${table(
123
+ ["Name", "Description"],
124
+ m.functions.map((f) => [`\`${f.signature}\``, f.description])
125
+ )}`
126
+ ).join("\n\n"),
127
+ selectors: renderSelectors(),
128
+ "allowed-methods": table(
129
+ ["Method", "On", "Description"],
130
+ ALLOWED_METHODS.map((m) => [
131
+ `\`.${m.signature}\``,
132
+ m.on.join(", "),
133
+ m.description,
134
+ ])
135
+ ),
136
+ });
137
+
138
+ const START = (name) => `<!-- generated:${name} -->`;
139
+ const END = "<!-- /generated -->";
140
+
141
+ /** Replace every region of `regions` found in `markdown`; throws on a missing one. */
142
+ export const spliceLanguageDocs = (
143
+ markdown,
144
+ regions = renderLanguageDocs()
145
+ ) => {
146
+ let out = markdown;
147
+ for (const [name, body] of Object.entries(regions)) {
148
+ const start = out.indexOf(START(name));
149
+ if (start < 0) throw new Error(`page is missing ${START(name)}`);
150
+ const from = start + START(name).length;
151
+ const end = out.indexOf(END, from);
152
+ if (end < 0) throw new Error(`page is missing ${END} after ${name}`);
153
+ out = `${out.slice(0, from)}\n${body}\n${out.slice(end)}`;
154
+ }
155
+ return out;
156
+ };
157
+
158
+ /** Current region bodies in `markdown`, keyed like `renderLanguageDocs`. */
159
+ export const readLanguageDocs = (markdown) => {
160
+ const regions = {};
161
+ for (const name of Object.keys(renderLanguageDocs())) {
162
+ const start = markdown.indexOf(START(name));
163
+ if (start < 0) continue;
164
+ const from = start + START(name).length;
165
+ const end = markdown.indexOf(END, from);
166
+ regions[name] = markdown.slice(from, end < 0 ? undefined : end).trim();
167
+ }
168
+ return regions;
169
+ };
170
+
171
+ const isCli = () => {
172
+ try {
173
+ return (
174
+ realpathSync(path.resolve(process.cwd(), process.argv[1] ?? "")) ===
175
+ realpathSync(fileURLToPath(import.meta.url))
176
+ );
177
+ } catch {
178
+ return false;
179
+ }
180
+ };
181
+
182
+ if (isCli()) {
183
+ const regions = renderLanguageDocs();
184
+ let updated = 0;
185
+ for (const [name, file] of Object.entries(REGION_FILES)) {
186
+ const page = path.join(DOCS_DIR, file);
187
+ const before = await readFile(page, "utf8");
188
+ const after = spliceLanguageDocs(before, { [name]: regions[name] });
189
+ if (after !== before) {
190
+ await writeFile(page, after, "utf8");
191
+ console.log(`updated ${path.relative(process.cwd(), page)}`);
192
+ updated++;
193
+ }
194
+ }
195
+ if (!updated) console.log("language docs already up to date");
196
+ }
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`css-variables view > writes --border-color for open and closed details > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 1,
6
+ "closest": 0,
7
+ "getVar": 0,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 1,
11
+ "parentElement": 1,
12
+ "quarkRuns": 1,
13
+ "queryScopeCost": 0,
14
+ "querySelectorAll": 0,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 1,
17
+ "schedulePaint": 1,
18
+ "setAttribute": 2,
19
+ "setVar": 0,
20
+ "textContent": 0,
21
+ "variableRuns": 0,
22
+ }
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`dispatch view > relays a click to the panel as a custom event the panel's own block turns into State > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 2,
6
+ "closest": 0,
7
+ "getVar": 2,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 0,
11
+ "parentElement": 1,
12
+ "quarkRuns": 0,
13
+ "queryScopeCost": 0,
14
+ "querySelectorAll": 1,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 0,
17
+ "schedulePaint": 2,
18
+ "setAttribute": 1,
19
+ "setVar": 1,
20
+ "textContent": 1,
21
+ "variableRuns": 1,
22
+ }
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`events view > prevents navigation and notes the event > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 0,
6
+ "closest": 0,
7
+ "getVar": 0,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 0,
11
+ "parentElement": 1,
12
+ "quarkRuns": 0,
13
+ "queryScopeCost": 0,
14
+ "querySelectorAll": 0,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 0,
17
+ "schedulePaint": 0,
18
+ "setAttribute": 0,
19
+ "setVar": 0,
20
+ "textContent": 1,
21
+ "variableRuns": 0,
22
+ }
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`iterate view > renders the planet list > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 0,
6
+ "closest": 0,
7
+ "getVar": 0,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 0,
11
+ "parentElement": 0,
12
+ "quarkRuns": 0,
13
+ "queryScopeCost": 0,
14
+ "querySelectorAll": 0,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 0,
17
+ "schedulePaint": 0,
18
+ "setAttribute": 0,
19
+ "setVar": 0,
20
+ "textContent": 0,
21
+ "variableRuns": 0,
22
+ }
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`js-api view > increments the click count through element.quark > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 1,
6
+ "closest": 1,
7
+ "getVar": 2,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 1,
11
+ "parentElement": 2,
12
+ "quarkRuns": 1,
13
+ "queryScopeCost": 3,
14
+ "querySelectorAll": 1,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 1,
17
+ "schedulePaint": 1,
18
+ "setAttribute": 0,
19
+ "setVar": 1,
20
+ "textContent": 1,
21
+ "variableRuns": 0,
22
+ }
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`provider-list view > iterates fetched todos > complexity 1`] = `
4
+ {
5
+ "attributeRuns": 0,
6
+ "closest": 0,
7
+ "getVar": 0,
8
+ "importNode": 0,
9
+ "listenerRuns": 0,
10
+ "matches": 0,
11
+ "parentElement": 0,
12
+ "quarkRuns": 0,
13
+ "queryScopeCost": 0,
14
+ "querySelectorAll": 0,
15
+ "removeAttribute": 0,
16
+ "ruleRuns": 0,
17
+ "schedulePaint": 0,
18
+ "setAttribute": 0,
19
+ "setVar": 0,
20
+ "textContent": 0,
21
+ "variableRuns": 0,
22
+ }
23
+ `;