jq79 0.5.0 → 0.5.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.
- package/dist/jq79.cjs +13 -13
- package/dist/jq79.cjs.map +1 -1
- package/dist/jq79.global.js +13 -13
- package/dist/jq79.global.js.map +1 -1
- package/dist/jq79.js +13 -13
- package/dist/jq79.js.map +1 -1
- package/package.json +1 -1
- package/src/jq79.ts +216 -19
package/package.json
CHANGED
package/src/jq79.ts
CHANGED
|
@@ -94,12 +94,95 @@ const compileExpr = (expr: string, params: string[]): Function | null => {
|
|
|
94
94
|
return fn
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
// a template expression is re-evaluated constantly - once per effect run, once
|
|
98
|
+
// per interpolation, once per :each item - so a value that is briefly undefined
|
|
99
|
+
// mid-render has to fail quietly, and the catch below stays. A ReferenceError
|
|
100
|
+
// is the one failure worth a word: `with` resolves a name against the store and
|
|
101
|
+
// then globalThis, so a name that resolves nowhere is declared nowhere - a
|
|
102
|
+
// typo, a dropped prop, or the trap this was written for, a top-level
|
|
103
|
+
// `function` declaration, which transformSetupScript leaves as an ordinary
|
|
104
|
+
// lexical binding instead of a store property
|
|
105
|
+
//
|
|
106
|
+
// It is reported late rather than where it throws, because "declared nowhere"
|
|
107
|
+
// is not yet decidable at that moment: a factory script assigns its bindings to
|
|
108
|
+
// the store when it returns, so an async factory renders its whole template
|
|
109
|
+
// before any of its names exist. Reporting waits until no script is still
|
|
110
|
+
// running (pendingScripts), and then asks whether the name resolves *now*.
|
|
111
|
+
//
|
|
112
|
+
// The re-check is `name in scope` rather than a re-evaluation, because
|
|
113
|
+
// re-evaluating is not pure: `@click="count++ + missing"` increments before it
|
|
114
|
+
// throws, and running it again to see if it still throws would increment twice
|
|
115
|
+
// and notify. `in` walks the same scope chain (:each scopes are
|
|
116
|
+
// Object.create(scope), :with is a proxy over it) and evaluates nothing
|
|
117
|
+
const MISSING_NAME_RE = /^(?:([\w$]+) is not defined|Can't find variable: ([\w$]+))/
|
|
118
|
+
|
|
119
|
+
// the queue holds live scopes, so it is capped: a script that never settles
|
|
120
|
+
// would otherwise let it grow for the life of the page
|
|
121
|
+
const MAX_PENDING_REPORTS = 100
|
|
122
|
+
|
|
123
|
+
type PendingReport = { name: string; expr: string; scope: Record<string, any> }
|
|
124
|
+
|
|
125
|
+
const pendingReports = new Map<string, PendingReport>()
|
|
126
|
+
const reportedExprErrors = new Set<string>()
|
|
127
|
+
let pendingScripts = 0
|
|
128
|
+
let flushScheduled = false
|
|
129
|
+
|
|
130
|
+
const flushExprReports = () => {
|
|
131
|
+
flushScheduled = false
|
|
132
|
+
if (pendingScripts > 0) return // a script started meanwhile; its release re-schedules
|
|
133
|
+
pendingReports.forEach(({ name, expr, scope }, key) => {
|
|
134
|
+
if (name in scope) return // it arrived late - a factory's bindings, a prop
|
|
135
|
+
reportedExprErrors.add(key)
|
|
136
|
+
console.warn(
|
|
137
|
+
`jq79: ${name} is not defined - evaluating "${expr}". Template expressions ` +
|
|
138
|
+
`resolve against the component store: a top-level let/var/const in a :setup ` +
|
|
139
|
+
`script, a declared prop, or a global. Note a "function name() {}" declaration ` +
|
|
140
|
+
`is not on the store - write "const name = () => {}".`
|
|
141
|
+
)
|
|
142
|
+
})
|
|
143
|
+
pendingReports.clear()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const scheduleExprReportFlush = () => {
|
|
147
|
+
if (flushScheduled || pendingScripts > 0 || !pendingReports.size) return
|
|
148
|
+
flushScheduled = true
|
|
149
|
+
queueMicrotask(flushExprReports)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// scripts run before the template renders, so the counter is already up when
|
|
153
|
+
// the first evaluation fails. Both script modes settle through a promise;
|
|
154
|
+
// the factory's has to cover the merge, not just the module body
|
|
155
|
+
const trackScript = (settled: Promise<unknown>) => {
|
|
156
|
+
pendingScripts++
|
|
157
|
+
const release = () => {
|
|
158
|
+
pendingScripts--
|
|
159
|
+
scheduleExprReportFlush()
|
|
160
|
+
}
|
|
161
|
+
settled.then(release, release)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const reportExprError = (expr: string, scope: Record<string, any>, error: unknown) => {
|
|
165
|
+
if (!(error instanceof ReferenceError)) return
|
|
166
|
+
const match = MISSING_NAME_RE.exec(error.message)
|
|
167
|
+
const name = match?.[1] ?? match?.[2]
|
|
168
|
+
if (!name) return // an engine whose wording we don't know: stay quiet, as before
|
|
169
|
+
// keyed on name and expression, not on the expression alone, so two missing
|
|
170
|
+
// names in one expression stay distinguishable - and so a :each of 1000 items
|
|
171
|
+
// enqueues one entry rather than 1000
|
|
172
|
+
const key = `${name}|${expr}`
|
|
173
|
+
if (reportedExprErrors.has(key) || pendingReports.has(key)) return
|
|
174
|
+
if (pendingReports.size >= MAX_PENDING_REPORTS) return
|
|
175
|
+
pendingReports.set(key, { name, expr, scope })
|
|
176
|
+
scheduleExprReportFlush()
|
|
177
|
+
}
|
|
178
|
+
|
|
97
179
|
const evalExpr = (expr: string, scope: Record<string, any>, extras?: Record<string, any>): any => {
|
|
98
180
|
const fn = compileExpr(expr, extras ? Object.keys(extras) : [])
|
|
99
181
|
if (!fn) return undefined
|
|
100
182
|
try {
|
|
101
183
|
return fn(scope, ...(extras ? Object.values(extras) : []))
|
|
102
|
-
} catch {
|
|
184
|
+
} catch (error) {
|
|
185
|
+
reportExprError(expr, scope, error)
|
|
103
186
|
return undefined
|
|
104
187
|
}
|
|
105
188
|
}
|
|
@@ -689,6 +772,7 @@ const renderNestedComponent = (key: string, node: TemplateNode, scope: Record<st
|
|
|
689
772
|
// or an undeclared name would be filtered on the first render and reappear
|
|
690
773
|
// on the next update
|
|
691
774
|
const declared = declaredPropSet(instance.scripts)
|
|
775
|
+
warnUndeclared(node, key, Object.keys(props), declared)
|
|
692
776
|
const seed = pickDeclared(untracked(resolveProps), declared)
|
|
693
777
|
// mounting into a fragment attaches no shadow root of its own: a
|
|
694
778
|
// shadow-rendered child keeps its <style> elements inline, next to the DOM
|
|
@@ -819,6 +903,41 @@ const normalizeAllowUrl = (policy: any): AllowUrl => {
|
|
|
819
903
|
return () => false
|
|
820
904
|
}
|
|
821
905
|
|
|
906
|
+
// HTML's boolean attributes, verbatim from the spec's list. Presence is the
|
|
907
|
+
// whole message for these: `disabled="false"` and `disabled="0"` both disable,
|
|
908
|
+
// so the value they carry is noise. This is a table of a fact, not of a jq79
|
|
909
|
+
// convention - nobody in this repo decides what belongs in it, which is what
|
|
910
|
+
// earns it a place in a codebase that otherwise has no name tables
|
|
911
|
+
const BOOLEAN_ATTRS = new Set([
|
|
912
|
+
"allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls",
|
|
913
|
+
"default", "defer", "disabled", "formnovalidate", "inert", "ismap",
|
|
914
|
+
"itemscope", "loop", "multiple", "muted", "nomodule", "novalidate", "open",
|
|
915
|
+
"playsinline", "readonly", "required", "reversed", "selected",
|
|
916
|
+
])
|
|
917
|
+
|
|
918
|
+
// the one value rule, shared by `:attr="expr"` and `:attrs` so the two forms
|
|
919
|
+
// can never disagree:
|
|
920
|
+
//
|
|
921
|
+
// - a boolean attribute is removed by ANY falsy value and set to "" when
|
|
922
|
+
// truthy, so `:disabled="items.length"` enables the button on an empty list
|
|
923
|
+
// (with `value !== false` as the only test, 0 set the attribute and disabled
|
|
924
|
+
// it - the trap renderComponent.test.ts used to pin);
|
|
925
|
+
// - every other attribute is removed only by null/undefined, so `false`, `0`
|
|
926
|
+
// and `""` are written. `aria-expanded="false"` and a `data-` flag mean
|
|
927
|
+
// something that absent cannot say.
|
|
928
|
+
//
|
|
929
|
+
// Asking the DOM which family a name belongs to (`typeof el[name] ===
|
|
930
|
+
// "boolean"`) is deliberately not what this does: jsdom and Chrome disagree on
|
|
931
|
+
// `autofocus` and every `aria-*`, so the tests would pin a semantics the
|
|
932
|
+
// browser doesn't have - and `readonly`/`novalidate`/`ismap` reflect under
|
|
933
|
+
// camelCase property names no kebab->camel pass can produce, failing toward
|
|
934
|
+
// `readonly="false"`, which is read-only
|
|
935
|
+
const applyAttr = (el: Element, name: string, value: any) => {
|
|
936
|
+
const boolean = BOOLEAN_ATTRS.has(name)
|
|
937
|
+
if (boolean ? !value : value == null) el.removeAttribute(name)
|
|
938
|
+
else el.setAttribute(name, boolean ? "" : String(value))
|
|
939
|
+
}
|
|
940
|
+
|
|
822
941
|
// renders a single element node: static attrs, @event listeners, a reactive
|
|
823
942
|
// :attrs object, and its content - :text/:html override the element's own
|
|
824
943
|
// children with a reactive textContent/innerHTML, otherwise children render
|
|
@@ -848,7 +967,11 @@ const renderNode = (node: TemplateNode, outerScope: Record<string, any>, fx: Eff
|
|
|
848
967
|
// imported component after `await`). Watch for the key: the effect tracks
|
|
849
968
|
// no deps, so it only re-runs on the store's new-key sweep, and swaps the
|
|
850
969
|
// placeholder element for the component exactly once
|
|
851
|
-
|
|
970
|
+
// dashes included, because findComponentKey matches them case-insensitively
|
|
971
|
+
// with dashes stripped: <drop-area> resolves DropArea, so a dashed tag is a
|
|
972
|
+
// possible component too, not only a custom element
|
|
973
|
+
const mayUpgrade = el instanceof HTMLUnknownElement || node.tag.includes("-")
|
|
974
|
+
if (mayUpgrade) {
|
|
852
975
|
let upgraded = false
|
|
853
976
|
fx.effect(() => {
|
|
854
977
|
if (upgraded) return
|
|
@@ -871,10 +994,30 @@ const renderNode = (node: TemplateNode, outerScope: Record<string, any>, fx: Eff
|
|
|
871
994
|
// the native-element form is parked there). Warn on a real element, but
|
|
872
995
|
// not on a tag that may still upgrade into a component - the upgrade
|
|
873
996
|
// re-renders through renderNestedComponent, models and all
|
|
874
|
-
if (!
|
|
997
|
+
if (!mayUpgrade) {
|
|
875
998
|
console.warn(`jq79: ${key} on <${node.tag}> does nothing - :model binds component tags only (for now)`)
|
|
876
999
|
}
|
|
877
|
-
} else if (
|
|
1000
|
+
} else if (isControlAttr(key)) {
|
|
1001
|
+
// a directive of its own, bound further down (or by renderNodes)
|
|
1002
|
+
} else if (key.startsWith(":")) {
|
|
1003
|
+
// :name="expr" binds that one attribute, reactively - the single-key
|
|
1004
|
+
// case :attrs="{ name: expr }" was carrying. `:name` alone is shorthand
|
|
1005
|
+
// for `:name="name"`, like props and :model.<name>, and the shorthand
|
|
1006
|
+
// reads the camelCase variable while the attribute keeps its written
|
|
1007
|
+
// (kebab) name: `:aria-expanded` binds `ariaExpanded`, because
|
|
1008
|
+
// `aria-expanded` as an expression is a subtraction.
|
|
1009
|
+
//
|
|
1010
|
+
// On a tag that may still upgrade this is a *parameter*, not an
|
|
1011
|
+
// attribute: leave it written verbatim, as before, so the upgrade's
|
|
1012
|
+
// renderNestedComponent still finds it. A component tag has no single
|
|
1013
|
+
// root for an attribute to land on anyway (TODOS/2026-07-15.class-directive.md)
|
|
1014
|
+
if (mayUpgrade) el.setAttribute(key, value)
|
|
1015
|
+
else {
|
|
1016
|
+
const name = key.slice(1)
|
|
1017
|
+
const expr = value || kebabToCamel(name)
|
|
1018
|
+
fx.effect(() => applyAttr(el, name, evalExpr(expr, scope)))
|
|
1019
|
+
}
|
|
1020
|
+
} else el.setAttribute(key, value)
|
|
878
1021
|
})
|
|
879
1022
|
|
|
880
1023
|
const bindExpr = node.attrs[":attrs"]
|
|
@@ -885,10 +1028,7 @@ const renderNode = (node: TemplateNode, outerScope: Record<string, any>, fx: Eff
|
|
|
885
1028
|
boundKeys.forEach(key => el.removeAttribute(key))
|
|
886
1029
|
const bound = evalExpr(bindExpr, scope)
|
|
887
1030
|
boundKeys = bound && typeof bound === "object" ? Object.keys(bound) : []
|
|
888
|
-
boundKeys.forEach(key =>
|
|
889
|
-
const value = bound[key]
|
|
890
|
-
if (value != null && value !== false) el.setAttribute(key, String(value))
|
|
891
|
-
})
|
|
1031
|
+
boundKeys.forEach(key => applyAttr(el, key, bound[key]))
|
|
892
1032
|
})
|
|
893
1033
|
}
|
|
894
1034
|
|
|
@@ -1625,6 +1765,7 @@ const runSetupScript = (code: string, scope: Record<string, any>, effect: (run:
|
|
|
1625
1765
|
`return (async () => { with ($scope) { ${code} } })()${sourceUrlComment(at.filename, at.index ?? 0)}`
|
|
1626
1766
|
)(scriptScope, effect, importer, ...Object.values(helpers))
|
|
1627
1767
|
result.catch(error => console.error("jq79: error in :setup script", error))
|
|
1768
|
+
trackScript(result)
|
|
1628
1769
|
}
|
|
1629
1770
|
|
|
1630
1771
|
// puts a component's declared props on the store, before any script runs and
|
|
@@ -1646,6 +1787,22 @@ const declareProps = (store: Record<string, any>, props: PropDecl[] | null) => {
|
|
|
1646
1787
|
})
|
|
1647
1788
|
}
|
|
1648
1789
|
|
|
1790
|
+
// a setup script's signature. A bare `<script :setup>` is a CLOSED signature -
|
|
1791
|
+
// the same as `<script :setup="{}">`, declaring zero props and taking none -
|
|
1792
|
+
// because the difference between "takes nothing" and "takes anything" should
|
|
1793
|
+
// not be a pair of braces somebody didn't type. Permissive is still reachable,
|
|
1794
|
+
// it just has to be asked for: `<script :setup="_">`, the same `_` convention
|
|
1795
|
+
// factory scripts already use, which parsePropsPattern reads as no signature.
|
|
1796
|
+
//
|
|
1797
|
+
// Only the empty *value* is closed. An absent attribute (a factory <script>
|
|
1798
|
+
// with no :setup at all) stays `null`, so its signature is still read from the
|
|
1799
|
+
// factory's first parameter
|
|
1800
|
+
const setupSignature = (script: TagBlock): PropDecl[] | null => {
|
|
1801
|
+
const pattern = script.attrs[":setup"]
|
|
1802
|
+
if (pattern === undefined) return null
|
|
1803
|
+
return pattern.trim() === "" ? [] : parsePropsPattern(pattern)
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1649
1806
|
// every prop name a component's scripts declare, across both script modes.
|
|
1650
1807
|
// Read before the store exists, because what a component declares decides
|
|
1651
1808
|
// which of its file's sibling components it can still see: declaring a name
|
|
@@ -1654,7 +1811,7 @@ const declareProps = (store: Record<string, any>, props: PropDecl[] | null) => {
|
|
|
1654
1811
|
const declaredPropNames = (scripts: TagBlock[]): Set<string> => {
|
|
1655
1812
|
const names = new Set<string>()
|
|
1656
1813
|
scripts.forEach(script => {
|
|
1657
|
-
const declarations = parseFactoryProps(script.content) ??
|
|
1814
|
+
const declarations = parseFactoryProps(script.content) ?? setupSignature(script)
|
|
1658
1815
|
declarations?.forEach(({ name }) => names.add(name))
|
|
1659
1816
|
})
|
|
1660
1817
|
return names
|
|
@@ -1662,13 +1819,13 @@ const declaredPropNames = (scripts: TagBlock[]): Set<string> => {
|
|
|
1662
1819
|
|
|
1663
1820
|
// the same names, but null when NO script declared a signature at all - the
|
|
1664
1821
|
// distinction declareProps already keeps, and the only one that can decide
|
|
1665
|
-
// whether to filter what a parent passes
|
|
1666
|
-
//
|
|
1667
|
-
//
|
|
1822
|
+
// whether to filter what a parent passes. `<script :setup>` and
|
|
1823
|
+
// `<script :setup="{}">` are both closed signatures that take nothing (see
|
|
1824
|
+
// setupSignature); `<script :setup="_">` is the permissive one
|
|
1668
1825
|
const declaredPropSet = (scripts: TagBlock[]): Set<string> | null => {
|
|
1669
1826
|
let names: Set<string> | null = null
|
|
1670
1827
|
scripts.forEach(script => {
|
|
1671
|
-
const declarations = parseFactoryProps(script.content) ??
|
|
1828
|
+
const declarations = parseFactoryProps(script.content) ?? setupSignature(script)
|
|
1672
1829
|
if (!declarations) return
|
|
1673
1830
|
const into = (names ??= new Set())
|
|
1674
1831
|
declarations.forEach(({ name }) => into.add(name))
|
|
@@ -1690,6 +1847,30 @@ const pickDeclared = (props: Record<string, any>, declared: Set<string> | null):
|
|
|
1690
1847
|
return out
|
|
1691
1848
|
}
|
|
1692
1849
|
|
|
1850
|
+
// names already reported by warnUndeclared, keyed by the template node - which
|
|
1851
|
+
// is the usage site itself, built once and shared by every instance it ever
|
|
1852
|
+
// renders. So a :each over 200 rows says it once, not once per row, and a
|
|
1853
|
+
// definition swap doesn't repeat what the last one already said
|
|
1854
|
+
const undeclaredWarned = new WeakMap<TemplateNode, Set<string>>()
|
|
1855
|
+
|
|
1856
|
+
// a parameter the child's signature doesn't declare is dropped by pickDeclared
|
|
1857
|
+
// and never reaches its store - `{{ bar }}` renders empty at the other end of
|
|
1858
|
+
// the file. Written parameters only: this is handed the named ones (`:bar`,
|
|
1859
|
+
// and the prop each :model binds), never a `:props` spread's keys, because a
|
|
1860
|
+
// spread of an object wider than the component is the documented, intended use
|
|
1861
|
+
// and taking only the declared few is its point - see pickDeclared. A
|
|
1862
|
+
// component with no signature at all declares nothing to compare against
|
|
1863
|
+
const warnUndeclared = (node: TemplateNode, name: string, written: string[], declared: Set<string> | null) => {
|
|
1864
|
+
if (declared === null) return
|
|
1865
|
+
const said = undeclaredWarned.get(node) ?? new Set<string>()
|
|
1866
|
+
undeclaredWarned.set(node, said)
|
|
1867
|
+
written.forEach(prop => {
|
|
1868
|
+
if (declared.has(prop) || said.has(prop)) return
|
|
1869
|
+
said.add(prop)
|
|
1870
|
+
console.warn(`jq79: :${prop} is not declared by <${name}> - add it to the :setup signature, or drop it`)
|
|
1871
|
+
})
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1693
1874
|
// the sibling components this one resolves by name, or null when there are
|
|
1694
1875
|
// none left to resolve. They go on the store's *prototype* rather than in it:
|
|
1695
1876
|
// the component-key scan walks the chain, so <Row> resolves; they stay out of
|
|
@@ -1741,11 +1922,16 @@ const runFactoryScript = (code: string, scope: Record<string, any>, effect: (run
|
|
|
1741
1922
|
|
|
1742
1923
|
const logError = (error: any) => console.error("jq79: error in factory script", error)
|
|
1743
1924
|
let invoked = false
|
|
1744
|
-
|
|
1745
|
-
|
|
1925
|
+
// what invoke() is still waiting on, memoized: it is called from both paths
|
|
1926
|
+
// below and does its work once, but the *second* caller is the one whose
|
|
1927
|
+
// promise is tracked - without this it would see `undefined` and count the
|
|
1928
|
+
// script as settled while an async factory's bindings are still on the way
|
|
1929
|
+
let merging: Promise<void> | undefined
|
|
1930
|
+
const invoke = (): Promise<void> | undefined => {
|
|
1931
|
+
if (invoked) return merging
|
|
1746
1932
|
invoked = true
|
|
1747
1933
|
const factory = $__exports.default
|
|
1748
|
-
if (typeof factory !== "function") return
|
|
1934
|
+
if (typeof factory !== "function") return undefined
|
|
1749
1935
|
const merge = (bindings: any) => {
|
|
1750
1936
|
if (bindings && typeof bindings === "object") Object.assign(scope, bindings)
|
|
1751
1937
|
}
|
|
@@ -1756,14 +1942,18 @@ const runFactoryScript = (code: string, scope: Record<string, any>, effect: (run
|
|
|
1756
1942
|
// the props it declared (copying, as destructuring does - $props is the
|
|
1757
1943
|
// live view for a primitive the parent reassigns later)
|
|
1758
1944
|
const returned = factory(scope, { $data: scope, $props: scope, $effect: effect, ...instanceHelpers })
|
|
1759
|
-
if (returned instanceof Promise) returned.then(merge).catch(logError)
|
|
1945
|
+
if (returned instanceof Promise) merging = returned.then(merge).catch(logError)
|
|
1760
1946
|
else merge(returned)
|
|
1761
1947
|
} catch (error) {
|
|
1762
1948
|
logError(error)
|
|
1763
1949
|
}
|
|
1950
|
+
return merging
|
|
1764
1951
|
}
|
|
1765
1952
|
|
|
1766
|
-
|
|
1953
|
+
// tracked through the merge, not just the module body: a factory's names
|
|
1954
|
+
// reach the store in `merge`, and a template expression that reads one before
|
|
1955
|
+
// then is not an authoring mistake (see reportExprError)
|
|
1956
|
+
trackScript(result.then(invoke, logError))
|
|
1767
1957
|
if ($__exports.done) invoke() // fully-sync body: factory runs before first render
|
|
1768
1958
|
}
|
|
1769
1959
|
|
|
@@ -1982,6 +2172,13 @@ export class Component79 {
|
|
|
1982
2172
|
// while its markers sit where its DOM actually is
|
|
1983
2173
|
hotReplace(src: string | ComponentParts): boolean {
|
|
1984
2174
|
const parts = typeof src === "string" ? parseComponentString(src) : src
|
|
2175
|
+
// the source just changed, so what was already said about it no longer
|
|
2176
|
+
// applies: without this the author fixes the typo, saves, and the next typo
|
|
2177
|
+
// in the same expression is deduped away against the old one. `compiled`
|
|
2178
|
+
// needs no such reset - it is keyed by expression text, so edited source is
|
|
2179
|
+
// a different key
|
|
2180
|
+
reportedExprErrors.clear()
|
|
2181
|
+
pendingReports.clear()
|
|
1985
2182
|
const marker = this.startMarker
|
|
1986
2183
|
const rendered = !!(marker && this.content)
|
|
1987
2184
|
|
|
@@ -2217,7 +2414,7 @@ export class Component79 {
|
|
|
2217
2414
|
return
|
|
2218
2415
|
}
|
|
2219
2416
|
const { vars, code } = transformSetupScript(script.content)
|
|
2220
|
-
declareProps(store,
|
|
2417
|
+
declareProps(store, setupSignature(script))
|
|
2221
2418
|
// pre-declare script vars on the store so `with` resolves assignments
|
|
2222
2419
|
// to them (and reads of them) through the reactive proxy
|
|
2223
2420
|
vars.forEach(name => { if (!(name in store)) (store as any)[name] = undefined })
|