@prestack/thread-ui 0.1.9 → 0.1.11
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.
- package/CHANGELOG.md +366 -0
- package/dist/ui/attach.js +6 -7
- package/dist/ui/compositions.d.ts +0 -2
- package/dist/ui/compositions.js +2 -112
- package/dist/ui/generators/routes.js +1 -0
- package/dist/ui/variant.d.ts +1 -3
- package/package.json +2 -2
- package/dist/ui/animations/anm_appear.ts +0 -13
- package/dist/ui/animations/anm_blur_in.ts +0 -19
- package/dist/ui/animations/anm_blur_out.ts +0 -18
- package/dist/ui/animations/anm_dismiss.ts +0 -18
- package/dist/ui/animations/anm_drop.ts +0 -19
- package/dist/ui/animations/anm_fall.ts +0 -18
- package/dist/ui/animations/anm_flash.ts +0 -18
- package/dist/ui/animations/anm_glow.ts +0 -16
- package/dist/ui/animations/anm_lift.ts +0 -16
- package/dist/ui/animations/anm_nudge.ts +0 -16
- package/dist/ui/animations/anm_pop_in.ts +0 -23
- package/dist/ui/animations/anm_pop_out.ts +0 -22
- package/dist/ui/animations/anm_press.ts +0 -12
- package/dist/ui/animations/anm_pulse.ts +0 -13
- package/dist/ui/animations/anm_rise.ts +0 -19
- package/dist/ui/animations/anm_shake.ts +0 -13
- package/dist/ui/animations/anm_slide_in_left.ts +0 -19
- package/dist/ui/animations/anm_slide_in_right.ts +0 -19
- package/dist/ui/animations/anm_slide_out_left.ts +0 -18
- package/dist/ui/animations/anm_slide_out_right.ts +0 -18
- package/dist/ui/animations/anm_spin.ts +0 -12
- package/dist/ui/animations/anm_swell.ts +0 -16
- package/dist/ui/animations/anm_wobble.ts +0 -24
- package/dist/ui/animations/anm_zoom_in.ts +0 -19
- package/dist/ui/animations/anm_zoom_out.ts +0 -18
- package/dist/ui/animations.ts +0 -308
- package/dist/ui/attach.ts +0 -553
- package/dist/ui/charts.tsx +0 -69
- package/dist/ui/checked.ts +0 -32
- package/dist/ui/collector.ts +0 -140
- package/dist/ui/compositions.ts +0 -555
- package/dist/ui/consent.ts +0 -55
- package/dist/ui/content.tsx +0 -27
- package/dist/ui/contrast.ts +0 -27
- package/dist/ui/controls.tsx +0 -25
- package/dist/ui/disclosure.tsx +0 -20
- package/dist/ui/dismiss-layer.ts +0 -87
- package/dist/ui/door.ts +0 -140
- package/dist/ui/drag.ts +0 -316
- package/dist/ui/elements/accordion.tsx +0 -47
- package/dist/ui/elements/accordion.works.ts +0 -66
- package/dist/ui/elements/aspect-ratio.tsx +0 -31
- package/dist/ui/elements/aspect-ratio.works.ts +0 -5
- package/dist/ui/elements/avatar.tsx +0 -34
- package/dist/ui/elements/avatar.works.ts +0 -16
- package/dist/ui/elements/badge.tsx +0 -33
- package/dist/ui/elements/badge.works.ts +0 -9
- package/dist/ui/elements/bars.tsx +0 -50
- package/dist/ui/elements/bars.works.ts +0 -29
- package/dist/ui/elements/box.tsx +0 -36
- package/dist/ui/elements/breadcrumb.tsx +0 -38
- package/dist/ui/elements/breadcrumb.works.ts +0 -24
- package/dist/ui/elements/button.tsx +0 -46
- package/dist/ui/elements/button.works.tsx +0 -52
- package/dist/ui/elements/column.tsx +0 -29
- package/dist/ui/elements/consent.tsx +0 -71
- package/dist/ui/elements/consent.works.tsx +0 -132
- package/dist/ui/elements/donut.tsx +0 -45
- package/dist/ui/elements/donut.works.ts +0 -42
- package/dist/ui/elements/each.tsx +0 -34
- package/dist/ui/elements/each.works.tsx +0 -82
- package/dist/ui/elements/empty.tsx +0 -33
- package/dist/ui/elements/field.tsx +0 -45
- package/dist/ui/elements/field.works.ts +0 -65
- package/dist/ui/elements/funnel.tsx +0 -50
- package/dist/ui/elements/funnel.works.ts +0 -37
- package/dist/ui/elements/gauge.tsx +0 -40
- package/dist/ui/elements/gauge.works.ts +0 -42
- package/dist/ui/elements/glyph.tsx +0 -30
- package/dist/ui/elements/glyph.works.tsx +0 -42
- package/dist/ui/elements/grid.tsx +0 -29
- package/dist/ui/elements/heatmap.tsx +0 -48
- package/dist/ui/elements/heatmap.works.ts +0 -24
- package/dist/ui/elements/hit-box.tsx +0 -47
- package/dist/ui/elements/hit-box.works.tsx +0 -576
- package/dist/ui/elements/image.tsx +0 -29
- package/dist/ui/elements/line-chart.tsx +0 -45
- package/dist/ui/elements/line-chart.works.ts +0 -41
- package/dist/ui/elements/link.tsx +0 -38
- package/dist/ui/elements/link.works.ts +0 -25
- package/dist/ui/elements/media.tsx +0 -57
- package/dist/ui/elements/menu.tsx +0 -51
- package/dist/ui/elements/menu.works.tsx +0 -154
- package/dist/ui/elements/money.tsx +0 -36
- package/dist/ui/elements/money.works.ts +0 -9
- package/dist/ui/elements/pagination.tsx +0 -39
- package/dist/ui/elements/pagination.works.ts +0 -20
- package/dist/ui/elements/progress.tsx +0 -34
- package/dist/ui/elements/progress.works.ts +0 -8
- package/dist/ui/elements/radio-group.tsx +0 -50
- package/dist/ui/elements/radio-group.works.ts +0 -33
- package/dist/ui/elements/row.tsx +0 -29
- package/dist/ui/elements/scatter.tsx +0 -42
- package/dist/ui/elements/scatter.works.ts +0 -38
- package/dist/ui/elements/select.tsx +0 -43
- package/dist/ui/elements/select.works.ts +0 -5
- package/dist/ui/elements/separator.tsx +0 -31
- package/dist/ui/elements/skeleton.tsx +0 -31
- package/dist/ui/elements/slider.tsx +0 -34
- package/dist/ui/elements/slider.works.ts +0 -5
- package/dist/ui/elements/sparkline.tsx +0 -37
- package/dist/ui/elements/sparkline.works.ts +0 -32
- package/dist/ui/elements/spinner.tsx +0 -33
- package/dist/ui/elements/stack.tsx +0 -29
- package/dist/ui/elements/stat.tsx +0 -36
- package/dist/ui/elements/stat.works.ts +0 -14
- package/dist/ui/elements/surface.tsx +0 -36
- package/dist/ui/elements/surface.works.ts +0 -9
- package/dist/ui/elements/table.tsx +0 -62
- package/dist/ui/elements/table.works.ts +0 -30
- package/dist/ui/elements/tabs.tsx +0 -47
- package/dist/ui/elements/tabs.works.ts +0 -84
- package/dist/ui/elements/text.tsx +0 -33
- package/dist/ui/elements/textarea.tsx +0 -38
- package/dist/ui/elements/textarea.works.ts +0 -5
- package/dist/ui/elements/time.tsx +0 -40
- package/dist/ui/elements/time.works.ts +0 -29
- package/dist/ui/elements/toggle.tsx +0 -34
- package/dist/ui/elements/toggle.works.ts +0 -5
- package/dist/ui/elements/tooltip.tsx +0 -40
- package/dist/ui/elements/tooltip.works.ts +0 -77
- package/dist/ui/elements/value.tsx +0 -38
- package/dist/ui/elements/value.works.ts +0 -9
- package/dist/ui/elements.ts +0 -127
- package/dist/ui/focus-scope.ts +0 -121
- package/dist/ui/fonts.ts +0 -355
- package/dist/ui/generators/dev.d.ts +0 -1
- package/dist/ui/generators/dev.js +0 -61
- package/dist/ui/generators/dev.ts +0 -74
- package/dist/ui/generators/elements.ts +0 -796
- package/dist/ui/generators/i18n.ts +0 -283
- package/dist/ui/generators/icons.ts +0 -207
- package/dist/ui/generators/react.ts +0 -267
- package/dist/ui/generators/routes.ts +0 -847
- package/dist/ui/generators/show.ts +0 -261
- package/dist/ui/generators/styles.ts +0 -677
- package/dist/ui/generators/variants.ts +0 -196
- package/dist/ui/i18n/catalogs/en.ts +0 -191
- package/dist/ui/i18n/format.ts +0 -221
- package/dist/ui/i18n/locales.ts +0 -33
- package/dist/ui/i18n/parse.ts +0 -315
- package/dist/ui/i18n/translator.ts +0 -31
- package/dist/ui/i18n/types.ts +0 -96
- package/dist/ui/icons.ts +0 -331
- package/dist/ui/islands/map.ts +0 -58
- package/dist/ui/localizations.ts +0 -75
- package/dist/ui/material.ts +0 -236
- package/dist/ui/materials/mat_bordered.ts +0 -13
- package/dist/ui/materials/mat_ceramic.ts +0 -13
- package/dist/ui/materials/mat_clay.ts +0 -13
- package/dist/ui/materials/mat_elevated.ts +0 -24
- package/dist/ui/materials/mat_flat.ts +0 -34
- package/dist/ui/materials/mat_glass.ts +0 -20
- package/dist/ui/materials/mat_lit.ts +0 -13
- package/dist/ui/materials/mat_moulded.ts +0 -11
- package/dist/ui/materials.ts +0 -197
- package/dist/ui/modes.ts +0 -44
- package/dist/ui/navigation.tsx +0 -29
- package/dist/ui/positioning.ts +0 -90
- package/dist/ui/presented.tsx +0 -119
- package/dist/ui/provider.tsx +0 -184
- package/dist/ui/render-loop.ts +0 -133
- package/dist/ui/roving-focus.ts +0 -161
- package/dist/ui/screens.ts +0 -141
- package/dist/ui/scroll-lock.ts +0 -28
- package/dist/ui/series.ts +0 -97
- package/dist/ui/signals.ts +0 -386
- package/dist/ui/styleguide.ts +0 -231
- package/dist/ui/styleguides.ts +0 -374
- package/dist/ui/themes.ts +0 -22
- package/dist/ui/token.ts +0 -78
- package/dist/ui/tokens/shadow.ts +0 -25
- package/dist/ui/tokens.ts +0 -234
- package/dist/ui/validators.ts +0 -232
- package/dist/ui/variant.ts +0 -352
- package/dist/ui/variants/var_avatar-round.ts +0 -14
- package/dist/ui/variants/var_bubble-me.ts +0 -14
- package/dist/ui/variants/var_bubble-them.ts +0 -13
- package/dist/ui/variants/var_button-border.ts +0 -76
- package/dist/ui/variants/var_button-cta.ts +0 -76
- package/dist/ui/variants/var_button-destructive-ghost.ts +0 -72
- package/dist/ui/variants/var_button-destructive.ts +0 -76
- package/dist/ui/variants/var_button-fill.ts +0 -76
- package/dist/ui/variants/var_button-ghost.ts +0 -72
- package/dist/ui/variants/var_button-glass.ts +0 -55
- package/dist/ui/variants/var_button-normal.ts +0 -76
- package/dist/ui/variants/var_button-quiet.ts +0 -74
- package/dist/ui/variants/var_card.ts +0 -17
- package/dist/ui/variants/var_chip.ts +0 -13
- package/dist/ui/variants/var_choice.ts +0 -15
- package/dist/ui/variants/var_framed.ts +0 -10
- package/dist/ui/variants/var_glyph-plain.ts +0 -11
- package/dist/ui/variants/var_input.ts +0 -43
- package/dist/ui/variants/var_link-inline.ts +0 -29
- package/dist/ui/variants/var_list-row.ts +0 -34
- package/dist/ui/variants/var_rule.ts +0 -10
- package/dist/ui/variants/var_skeleton-block.ts +0 -12
- package/dist/ui/variants/var_spinner-turning.ts +0 -12
- package/dist/ui/variants/var_stat-tile.ts +0 -13
- package/dist/ui/variants/var_tab-bar.ts +0 -15
- package/dist/ui/variants/var_tap-target.ts +0 -25
- package/dist/ui/variants.ts +0 -64
- 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
|
-
}
|