@prestack/thread-ui 0.1.10 → 0.1.12

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 (209) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/dist/ui/attach.js +6 -7
  3. package/dist/ui/compositions.d.ts +0 -8
  4. package/dist/ui/compositions.js +3 -166
  5. package/dist/ui/generators/routes.js +1 -0
  6. package/package.json +2 -2
  7. package/dist/ui/animations/anm_appear.ts +0 -13
  8. package/dist/ui/animations/anm_blur_in.ts +0 -19
  9. package/dist/ui/animations/anm_blur_out.ts +0 -18
  10. package/dist/ui/animations/anm_dismiss.ts +0 -18
  11. package/dist/ui/animations/anm_drop.ts +0 -19
  12. package/dist/ui/animations/anm_fall.ts +0 -18
  13. package/dist/ui/animations/anm_flash.ts +0 -18
  14. package/dist/ui/animations/anm_glow.ts +0 -16
  15. package/dist/ui/animations/anm_lift.ts +0 -16
  16. package/dist/ui/animations/anm_nudge.ts +0 -16
  17. package/dist/ui/animations/anm_pop_in.ts +0 -23
  18. package/dist/ui/animations/anm_pop_out.ts +0 -22
  19. package/dist/ui/animations/anm_press.ts +0 -12
  20. package/dist/ui/animations/anm_pulse.ts +0 -13
  21. package/dist/ui/animations/anm_rise.ts +0 -19
  22. package/dist/ui/animations/anm_shake.ts +0 -13
  23. package/dist/ui/animations/anm_slide_in_left.ts +0 -19
  24. package/dist/ui/animations/anm_slide_in_right.ts +0 -19
  25. package/dist/ui/animations/anm_slide_out_left.ts +0 -18
  26. package/dist/ui/animations/anm_slide_out_right.ts +0 -18
  27. package/dist/ui/animations/anm_spin.ts +0 -12
  28. package/dist/ui/animations/anm_swell.ts +0 -16
  29. package/dist/ui/animations/anm_wobble.ts +0 -24
  30. package/dist/ui/animations/anm_zoom_in.ts +0 -19
  31. package/dist/ui/animations/anm_zoom_out.ts +0 -18
  32. package/dist/ui/animations.ts +0 -308
  33. package/dist/ui/attach.ts +0 -553
  34. package/dist/ui/charts.tsx +0 -69
  35. package/dist/ui/checked.ts +0 -32
  36. package/dist/ui/collector.ts +0 -140
  37. package/dist/ui/compositions.ts +0 -613
  38. package/dist/ui/consent.ts +0 -55
  39. package/dist/ui/content.tsx +0 -27
  40. package/dist/ui/contrast.ts +0 -27
  41. package/dist/ui/controls.tsx +0 -25
  42. package/dist/ui/disclosure.tsx +0 -20
  43. package/dist/ui/dismiss-layer.ts +0 -87
  44. package/dist/ui/door.ts +0 -140
  45. package/dist/ui/drag.ts +0 -316
  46. package/dist/ui/elements/accordion.tsx +0 -47
  47. package/dist/ui/elements/accordion.works.ts +0 -66
  48. package/dist/ui/elements/aspect-ratio.tsx +0 -31
  49. package/dist/ui/elements/aspect-ratio.works.ts +0 -5
  50. package/dist/ui/elements/avatar.tsx +0 -34
  51. package/dist/ui/elements/avatar.works.ts +0 -16
  52. package/dist/ui/elements/badge.tsx +0 -33
  53. package/dist/ui/elements/badge.works.ts +0 -9
  54. package/dist/ui/elements/bars.tsx +0 -50
  55. package/dist/ui/elements/bars.works.ts +0 -29
  56. package/dist/ui/elements/box.tsx +0 -36
  57. package/dist/ui/elements/breadcrumb.tsx +0 -38
  58. package/dist/ui/elements/breadcrumb.works.ts +0 -24
  59. package/dist/ui/elements/button.tsx +0 -46
  60. package/dist/ui/elements/button.works.tsx +0 -52
  61. package/dist/ui/elements/column.tsx +0 -29
  62. package/dist/ui/elements/consent.tsx +0 -71
  63. package/dist/ui/elements/consent.works.tsx +0 -132
  64. package/dist/ui/elements/donut.tsx +0 -45
  65. package/dist/ui/elements/donut.works.ts +0 -42
  66. package/dist/ui/elements/each.tsx +0 -34
  67. package/dist/ui/elements/each.works.tsx +0 -82
  68. package/dist/ui/elements/empty.tsx +0 -33
  69. package/dist/ui/elements/field.tsx +0 -45
  70. package/dist/ui/elements/field.works.ts +0 -65
  71. package/dist/ui/elements/funnel.tsx +0 -50
  72. package/dist/ui/elements/funnel.works.ts +0 -37
  73. package/dist/ui/elements/gauge.tsx +0 -40
  74. package/dist/ui/elements/gauge.works.ts +0 -42
  75. package/dist/ui/elements/glyph.tsx +0 -30
  76. package/dist/ui/elements/glyph.works.tsx +0 -42
  77. package/dist/ui/elements/grid.tsx +0 -29
  78. package/dist/ui/elements/heatmap.tsx +0 -48
  79. package/dist/ui/elements/heatmap.works.ts +0 -24
  80. package/dist/ui/elements/hit-box.tsx +0 -47
  81. package/dist/ui/elements/hit-box.works.tsx +0 -576
  82. package/dist/ui/elements/image.tsx +0 -29
  83. package/dist/ui/elements/line-chart.tsx +0 -45
  84. package/dist/ui/elements/line-chart.works.ts +0 -41
  85. package/dist/ui/elements/link.tsx +0 -38
  86. package/dist/ui/elements/link.works.ts +0 -25
  87. package/dist/ui/elements/media.tsx +0 -57
  88. package/dist/ui/elements/menu.tsx +0 -51
  89. package/dist/ui/elements/menu.works.tsx +0 -154
  90. package/dist/ui/elements/money.tsx +0 -36
  91. package/dist/ui/elements/money.works.ts +0 -9
  92. package/dist/ui/elements/pagination.tsx +0 -39
  93. package/dist/ui/elements/pagination.works.ts +0 -20
  94. package/dist/ui/elements/progress.tsx +0 -34
  95. package/dist/ui/elements/progress.works.ts +0 -8
  96. package/dist/ui/elements/radio-group.tsx +0 -50
  97. package/dist/ui/elements/radio-group.works.ts +0 -33
  98. package/dist/ui/elements/row.tsx +0 -29
  99. package/dist/ui/elements/scatter.tsx +0 -42
  100. package/dist/ui/elements/scatter.works.ts +0 -38
  101. package/dist/ui/elements/select.tsx +0 -43
  102. package/dist/ui/elements/select.works.ts +0 -5
  103. package/dist/ui/elements/separator.tsx +0 -31
  104. package/dist/ui/elements/skeleton.tsx +0 -31
  105. package/dist/ui/elements/slider.tsx +0 -34
  106. package/dist/ui/elements/slider.works.ts +0 -5
  107. package/dist/ui/elements/sparkline.tsx +0 -37
  108. package/dist/ui/elements/sparkline.works.ts +0 -32
  109. package/dist/ui/elements/spinner.tsx +0 -33
  110. package/dist/ui/elements/stack.tsx +0 -29
  111. package/dist/ui/elements/stat.tsx +0 -36
  112. package/dist/ui/elements/stat.works.ts +0 -14
  113. package/dist/ui/elements/surface.tsx +0 -36
  114. package/dist/ui/elements/surface.works.ts +0 -9
  115. package/dist/ui/elements/table.tsx +0 -62
  116. package/dist/ui/elements/table.works.ts +0 -30
  117. package/dist/ui/elements/tabs.tsx +0 -47
  118. package/dist/ui/elements/tabs.works.ts +0 -84
  119. package/dist/ui/elements/text.tsx +0 -33
  120. package/dist/ui/elements/textarea.tsx +0 -38
  121. package/dist/ui/elements/textarea.works.ts +0 -5
  122. package/dist/ui/elements/time.tsx +0 -40
  123. package/dist/ui/elements/time.works.ts +0 -29
  124. package/dist/ui/elements/toggle.tsx +0 -34
  125. package/dist/ui/elements/toggle.works.ts +0 -5
  126. package/dist/ui/elements/tooltip.tsx +0 -40
  127. package/dist/ui/elements/tooltip.works.ts +0 -77
  128. package/dist/ui/elements/value.tsx +0 -38
  129. package/dist/ui/elements/value.works.ts +0 -9
  130. package/dist/ui/elements.ts +0 -127
  131. package/dist/ui/focus-scope.ts +0 -121
  132. package/dist/ui/fonts.ts +0 -355
  133. package/dist/ui/generators/dev.d.ts +0 -1
  134. package/dist/ui/generators/dev.js +0 -62
  135. package/dist/ui/generators/dev.ts +0 -75
  136. package/dist/ui/generators/elements.ts +0 -796
  137. package/dist/ui/generators/i18n.ts +0 -283
  138. package/dist/ui/generators/icons.ts +0 -207
  139. package/dist/ui/generators/react.ts +0 -267
  140. package/dist/ui/generators/routes.ts +0 -847
  141. package/dist/ui/generators/show.ts +0 -261
  142. package/dist/ui/generators/styles.ts +0 -677
  143. package/dist/ui/generators/variants.ts +0 -196
  144. package/dist/ui/i18n/catalogs/en.ts +0 -191
  145. package/dist/ui/i18n/format.ts +0 -221
  146. package/dist/ui/i18n/locales.ts +0 -33
  147. package/dist/ui/i18n/parse.ts +0 -315
  148. package/dist/ui/i18n/translator.ts +0 -31
  149. package/dist/ui/i18n/types.ts +0 -96
  150. package/dist/ui/icons.ts +0 -331
  151. package/dist/ui/islands/map.ts +0 -58
  152. package/dist/ui/localizations.ts +0 -75
  153. package/dist/ui/material.ts +0 -236
  154. package/dist/ui/materials/mat_bordered.ts +0 -13
  155. package/dist/ui/materials/mat_ceramic.ts +0 -13
  156. package/dist/ui/materials/mat_clay.ts +0 -13
  157. package/dist/ui/materials/mat_elevated.ts +0 -24
  158. package/dist/ui/materials/mat_flat.ts +0 -34
  159. package/dist/ui/materials/mat_glass.ts +0 -20
  160. package/dist/ui/materials/mat_lit.ts +0 -13
  161. package/dist/ui/materials/mat_moulded.ts +0 -11
  162. package/dist/ui/materials.ts +0 -197
  163. package/dist/ui/modes.ts +0 -44
  164. package/dist/ui/navigation.tsx +0 -29
  165. package/dist/ui/positioning.ts +0 -90
  166. package/dist/ui/presented.tsx +0 -119
  167. package/dist/ui/provider.tsx +0 -184
  168. package/dist/ui/render-loop.ts +0 -133
  169. package/dist/ui/roving-focus.ts +0 -161
  170. package/dist/ui/screens.ts +0 -141
  171. package/dist/ui/scroll-lock.ts +0 -28
  172. package/dist/ui/series.ts +0 -97
  173. package/dist/ui/signals.ts +0 -386
  174. package/dist/ui/styleguide.ts +0 -231
  175. package/dist/ui/styleguides.ts +0 -374
  176. package/dist/ui/themes.ts +0 -22
  177. package/dist/ui/token.ts +0 -78
  178. package/dist/ui/tokens/shadow.ts +0 -25
  179. package/dist/ui/tokens.ts +0 -234
  180. package/dist/ui/validators.ts +0 -232
  181. package/dist/ui/variant.ts +0 -349
  182. package/dist/ui/variants/var_avatar-round.ts +0 -14
  183. package/dist/ui/variants/var_bubble-me.ts +0 -14
  184. package/dist/ui/variants/var_bubble-them.ts +0 -13
  185. package/dist/ui/variants/var_button-border.ts +0 -76
  186. package/dist/ui/variants/var_button-cta.ts +0 -76
  187. package/dist/ui/variants/var_button-destructive-ghost.ts +0 -72
  188. package/dist/ui/variants/var_button-destructive.ts +0 -76
  189. package/dist/ui/variants/var_button-fill.ts +0 -76
  190. package/dist/ui/variants/var_button-ghost.ts +0 -72
  191. package/dist/ui/variants/var_button-glass.ts +0 -55
  192. package/dist/ui/variants/var_button-normal.ts +0 -76
  193. package/dist/ui/variants/var_button-quiet.ts +0 -74
  194. package/dist/ui/variants/var_card.ts +0 -17
  195. package/dist/ui/variants/var_chip.ts +0 -13
  196. package/dist/ui/variants/var_choice.ts +0 -15
  197. package/dist/ui/variants/var_framed.ts +0 -10
  198. package/dist/ui/variants/var_glyph-plain.ts +0 -11
  199. package/dist/ui/variants/var_input.ts +0 -43
  200. package/dist/ui/variants/var_link-inline.ts +0 -29
  201. package/dist/ui/variants/var_list-row.ts +0 -34
  202. package/dist/ui/variants/var_rule.ts +0 -10
  203. package/dist/ui/variants/var_skeleton-block.ts +0 -12
  204. package/dist/ui/variants/var_spinner-turning.ts +0 -12
  205. package/dist/ui/variants/var_stat-tile.ts +0 -13
  206. package/dist/ui/variants/var_tab-bar.ts +0 -15
  207. package/dist/ui/variants/var_tap-target.ts +0 -25
  208. package/dist/ui/variants.ts +0 -64
  209. package/dist/ui/wrappers.tsx +0 -429
@@ -1,267 +0,0 @@
1
- import { createHash } from 'node:crypto'
2
- import { existsSync, readFileSync, statSync } from '@prestack/thread/integrations/disk'
3
- import { cwd } from 'node:process'
4
- import { dirname, join, resolve } from 'node:path'
5
-
6
- import ts from 'typescript'
7
-
8
- import { idOf } from '../checked.ts'
9
- import { classOf } from '../variant.ts'
10
-
11
- const OWNED = /\.(t|j)sx$/
12
-
13
- const VARIANT_MEMBER = /^[a-z]/
14
-
15
- interface Edit {
16
- readonly from: number
17
- readonly to: number
18
- readonly text: string
19
- }
20
-
21
- interface Arranging {
22
- readonly from: number
23
- readonly to: number
24
- readonly own: string
25
- }
26
-
27
- const ARRANGERS = new Set(['composition', 'screen'])
28
-
29
- const HOST = /^[a-z]/
30
-
31
- const MAKES = 'element'
32
-
33
- const ONE_WORD = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/
34
-
35
- function prefixed(called: string): string {
36
- return called === 'screen' ? 's-' : 'c-'
37
- }
38
-
39
- function quoted(node: ts.Node): string | undefined {
40
- return ts.isStringLiteral(node) ? node.text : undefined
41
- }
42
-
43
- function joined(held: readonly string[]): string {
44
- return held.filter((one) => one !== '').join(' ')
45
- }
46
-
47
- function arranging(held: readonly Arranging[], at: number): string | undefined {
48
- let found: Arranging | undefined
49
- for (const one of held) {
50
- if (at < one.from || at >= one.to) continue
51
- if (found === undefined || one.from > found.from) found = one
52
- }
53
- return found?.own
54
- }
55
-
56
- function within(held: readonly { readonly from: number; readonly to: number }[], at: number): boolean {
57
- return held.some((one) => at >= one.from && at < one.to)
58
- }
59
-
60
- function tagOf(node: ts.JsxOpeningElement | ts.JsxSelfClosingElement | ts.JsxClosingElement): ts.JsxTagNameExpression {
61
- return node.tagName
62
- }
63
-
64
- function attributes(node: ts.JsxOpeningElement | ts.JsxSelfClosingElement): ts.JsxAttributes {
65
- return node.attributes
66
- }
67
-
68
- interface Held {
69
- readonly at?: ts.JsxAttribute
70
- readonly className?: ts.JsxAttribute
71
- }
72
-
73
- function named(held: ts.JsxAttributes): Held {
74
- let at: ts.JsxAttribute | undefined
75
- let className: ts.JsxAttribute | undefined
76
- for (const one of held.properties) {
77
- if (!ts.isJsxAttribute(one) || !ts.isIdentifier(one.name)) continue
78
- if (one.name.text === 'at') at = one
79
- if (one.name.text === 'className') className = one
80
- }
81
- return {
82
- ...(at === undefined ? {} : { at }),
83
- ...(className === undefined ? {} : { className }),
84
- }
85
- }
86
-
87
- function wearing(held: ts.JsxAttribute | undefined, added: string, text: string): string {
88
- if (held?.initializer === undefined) return `className="${added}"`
89
- const value = held.initializer
90
- if (ts.isStringLiteral(value)) return `className="${joined([value.text, added])}"`
91
- const inner = text.slice(value.getStart() + 1, value.getEnd() - 1)
92
- return `className={\`\${${inner}} ${added}\`}`
93
- }
94
-
95
- export function compiled(text: string, at: string): { readonly text?: string; readonly because?: string } {
96
- const file = ts.createSourceFile(at, text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX)
97
-
98
- const arranges: Arranging[] = []
99
- const edits: Edit[] = []
100
- let because: string | undefined
101
- const writing: { readonly from: number; readonly to: number }[] = []
102
-
103
- const calls = (node: ts.Node): void => {
104
- if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === MAKES) {
105
- writing.push({ from: node.getStart(), to: node.getEnd() })
106
- }
107
- if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && ARRANGERS.has(node.expression.text)) {
108
- const first = node.arguments[0]
109
- const said = first === undefined ? undefined : quoted(first)
110
- if (first !== undefined && said !== undefined) {
111
- if (!ONE_WORD.test(said)) {
112
- because =
113
- `${at} names a ${node.expression.text} "${said}", and that name becomes the class everything inside ` +
114
- 'it is arranged against. This one is not a single word, so it would become two classes and neither ' +
115
- 'would be the one the stylesheet writes'
116
- }
117
- const own = `${prefixed(node.expression.text)}${idOf(said)}`
118
- arranges.push({ from: node.getStart(), to: node.getEnd(), own })
119
- edits.push({ from: first.getStart(), to: first.getEnd(), text: `'${own}'` })
120
- }
121
- }
122
- ts.forEachChild(node, calls)
123
- }
124
- calls(file)
125
-
126
- const tags = (node: ts.Node): void => {
127
- if (ts.isJsxClosingElement(node)) {
128
- const tag = tagOf(node)
129
- if (ts.isPropertyAccessExpression(tag) && VARIANT_MEMBER.test(tag.name.text)) {
130
- edits.push({ from: tag.getStart(), to: tag.getEnd(), text: tag.expression.getText() })
131
- }
132
- }
133
-
134
- if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
135
- const tag = tagOf(node)
136
- const held = named(attributes(node))
137
- const worn: string[] = []
138
-
139
- if (ts.isIdentifier(tag) && HOST.test(tag.text) && !within(writing, node.getStart())) {
140
- because =
141
- `${at} writes <${tag.text}>, which is a host element: it wears no declared style, sits in no ` +
142
- 'catalogue, and the style guide, a rebrand and every overlay read past it. Declare the element ' +
143
- 'and wear its look, or use the declared groupings where a host element would have gone'
144
- }
145
-
146
- if (held.className !== undefined && !within(writing, node.getStart())) {
147
- because =
148
- `${at} writes a \`className\` by hand, which is CSS written in place: it names no style guide ` +
149
- 'row, wears no declared variant, and the style guide, a rebrand and every overlay read past ' +
150
- 'it. Declare a variant and wear it — `Box.card` — or name a place with `at`, which the build ' +
151
- 'turns into the class the arrangement already declares'
152
- }
153
-
154
- if (ts.isPropertyAccessExpression(tag) && VARIANT_MEMBER.test(tag.name.text)) {
155
- worn.push(classOf(idOf(tag.name.text)))
156
- edits.push({ from: tag.getStart(), to: tag.getEnd(), text: tag.expression.getText() })
157
- }
158
-
159
- if (held.at !== undefined) {
160
- const place = held.at.initializer === undefined ? undefined : quoted(held.at.initializer)
161
- if (place === undefined) {
162
- because = `${at} gives a place that is not written out where it is used. A place is a class the build joins, so it has to be a plain word here`
163
- } else {
164
- const own = arranging(arranges, node.getStart())
165
- if (own === undefined) {
166
- because =
167
- `${at} names the place "${place}" outside any composition or screen, and a place is declared by ` +
168
- 'whatever arranges it. Nothing arranges this one, so the name points at nothing'
169
- } else {
170
- worn.push(`${own}-${place}`)
171
- }
172
- }
173
- edits.push({ from: held.at.getFullStart(), to: held.at.getEnd(), text: '' })
174
- }
175
-
176
- if (worn.length > 0) {
177
- const wrote = wearing(held.className, joined(worn), text)
178
- if (held.className === undefined) edits.push({ from: tag.getEnd(), to: tag.getEnd(), text: ` ${wrote}` })
179
- else edits.push({ from: held.className.getStart(), to: held.className.getEnd(), text: wrote })
180
- }
181
- }
182
-
183
- ts.forEachChild(node, tags)
184
- }
185
- tags(file)
186
-
187
- if (because !== undefined) return { because }
188
- if (edits.length === 0) return { text }
189
-
190
- let made = text
191
- for (const one of [...edits].sort((a, b) => b.from - a.from)) {
192
- made = made.slice(0, one.from) + one.text + made.slice(one.to)
193
- }
194
- return { text: made }
195
- }
196
-
197
- interface Loading {
198
- readonly onLoad: (
199
- opts: { filter: RegExp },
200
- run: (args: { path: string }) => { contents?: string; loader?: string; errors?: readonly { text: string }[] } | undefined,
201
- ) => void
202
- }
203
-
204
- let checked: string | null | undefined
205
- let against: string | undefined
206
-
207
- function treeAt(from: string): string | undefined {
208
- for (const start of [dirname(resolve(from)), resolve(cwd())]) {
209
- let root = start
210
- while (root !== dirname(root)) {
211
- if (existsSync(join(root, '.thread', 'gate.json')) || existsSync(join(root, '_threads'))) return root
212
- root = dirname(root)
213
- }
214
- }
215
- return undefined
216
- }
217
-
218
- export function ungated(from: string): string | null {
219
- const root = treeAt(from)
220
- const at = root === undefined ? '' : join(root, '.thread', 'gate.json')
221
-
222
- const stamp = at !== '' && existsSync(at) ? `${String(statSync(at).mtimeMs)}:${String(statSync(at).size)}` : `none:${from}`
223
- if (checked !== undefined && against === stamp) return checked
224
- against = stamp
225
- checked = null
226
-
227
- if (at === '' || !existsSync(at)) {
228
- checked =
229
- 'this tree has no passing gate, so nothing in it may compile. Run `thread gate`. A gate that has never run is not a ' +
230
- 'gate that passed, and the file you are compiling was never measured. Compiling ' +
231
- `\`${from}\`, it looked for a gate receipt from \`${dirname(resolve(from))}\` and from ` +
232
- `\`${resolve(cwd())}\` upwards${at === '' ? ', and neither reached a tree' : `, and found none at ${at}`}`
233
- return checked
234
- }
235
- const held = JSON.parse(readFileSync(at, 'utf8')) as { of?: Record<string, string> }
236
- for (const [named, was] of Object.entries(held.of ?? {})) {
237
- const now = existsSync(join(dirname(dirname(at)), named))
238
- ? createHash('sha256').update(readFileSync(join(dirname(dirname(at)), named))).digest('hex').slice(0, 16)
239
- : 'gone'
240
- if (now === was) continue
241
- checked = `${named} has changed since the gate last passed, so what this tree declares and what it was measured as no longer agree. Run \`thread gate\``
242
- return checked
243
- }
244
- return checked
245
- }
246
-
247
- export default function loader(this: { readonly resourcePath?: string } | void, source: string): string {
248
- const at = typeof this?.resourcePath === 'string' ? this.resourcePath : ''
249
- const skipped = at === '' ? null : ungated(at)
250
- if (skipped !== null) throw new Error(`thread: ${skipped}.`)
251
- const made = compiled(source, at)
252
-
253
- if (made.because !== undefined) throw new Error(made.because)
254
- return made.text ?? source
255
- }
256
-
257
- export const plugin: { readonly name: string; readonly setup: (build: Loading) => void } = {
258
- name: 'thread-react',
259
- setup(build) {
260
- build.onLoad({ filter: OWNED }, (args) => {
261
- const text = readFileSync(args.path, 'utf8')
262
- const made = compiled(text, args.path)
263
- if (made.because !== undefined) return { errors: [{ text: made.because }] }
264
- return { contents: made.text ?? text, loader: 'tsx' }
265
- })
266
- },
267
- }