sygnal 6.6.0 → 7.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.
- package/CHANGELOG.md +258 -0
- package/README.md +2 -0
- package/dist/astro/index.cjs.js +32 -9
- package/dist/astro/index.cjs.js.map +1 -1
- package/dist/astro/index.mjs +32 -9
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/server.cjs.js +32 -43
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs +32 -43
- package/dist/astro/server.mjs.map +1 -1
- package/dist/devtools.cjs.js.map +1 -1
- package/dist/devtools.esm.js.map +1 -1
- package/dist/diagnostics.cjs.js +154 -6
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +153 -7
- package/dist/diagnostics.esm.js.map +1 -1
- package/dist/guide/accessibility.md +3 -1
- package/dist/guide/ai-chat.md +6 -6
- package/dist/guide/behaviors.md +1 -1
- package/dist/guide/element-commands.md +4 -2
- package/dist/guide/forms-reference.md +89 -3
- package/dist/guide/forms.md +8 -8
- package/dist/guide/http.md +77 -7
- package/dist/guide/migrating-to-7.md +314 -0
- package/dist/guide/recipes/ai-summarize.md +2 -1
- package/dist/guide/recipes/i18n.md +1 -1
- package/dist/guide/resources.md +2 -0
- package/dist/guide/timers.md +3 -3
- package/dist/guide/ui/tabs.md +5 -4
- package/dist/guide/ui/tooltip.md +24 -0
- package/dist/index.cjs.js +954 -388
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +300 -46
- package/dist/index.esm.js +953 -389
- package/dist/index.esm.js.map +1 -1
- package/dist/sygnal.min.js +1 -1
- package/dist/sygnal.min.js.map +1 -1
- package/dist/ui.cjs.js +96 -11
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +96 -12
- package/dist/ui.esm.js.map +1 -1
- package/dist/vike/config/package.json +1 -1
- package/dist/vite/plugin.cjs.js +19 -9
- package/dist/vite/plugin.cjs.js.map +1 -1
- package/dist/vite/plugin.mjs +19 -9
- package/dist/vite/plugin.mjs.map +1 -1
- package/llms.txt +23 -22
- package/package.json +1 -1
- package/src/astro/index.d.ts +8 -0
- package/src/astro/index.ts +18 -0
- package/src/core/actions.ts +28 -21
- package/src/core/define.ts +2 -0
- package/src/core/hooks.ts +2 -2
- package/src/core/hosts/collection.ts +4 -3
- package/src/core/hosts/switchable.ts +26 -8
- package/src/core/instance.ts +66 -17
- package/src/core/runtime.ts +5 -1
- package/src/core/statics.ts +5 -5
- package/src/extra/ai/chat/behavior.ts +3 -3
- package/src/extra/ai/commandBar.ts +3 -3
- package/src/extra/ai/compose/behavior.ts +3 -3
- package/src/extra/ai/transports/shared.ts +10 -2
- package/src/extra/behaviors.ts +24 -3
- package/src/extra/diagnostics/checks/fetch.ts +21 -1
- package/src/extra/diagnostics/checks/forms.ts +4 -3
- package/src/extra/diagnostics/checks/index.ts +1 -0
- package/src/extra/diagnostics/checks/next.ts +49 -3
- package/src/extra/diagnostics/checks/props.ts +6 -1
- package/src/extra/diagnostics/checks/public.d.ts +12 -0
- package/src/extra/diagnostics/checks/timingAudit.ts +47 -0
- package/src/extra/diagnostics/codes.ts +24 -0
- package/src/extra/fetchDriver.ts +115 -7
- package/src/extra/fetchEventSource.ts +117 -0
- package/src/extra/form.ts +68 -26
- package/src/extra/formHelpers.ts +3 -1
- package/src/extra/lens.ts +3 -2
- package/src/extra/queryCache.ts +4 -3
- package/src/extra/socketDriver.ts +60 -9
- package/src/extra/ssr.ts +30 -41
- package/src/extra/testing.ts +100 -18
- package/src/extra/timers.ts +5 -2
- package/src/index.d.ts +299 -45
- package/src/index.ts +3 -0
- package/src/shared.ts +3 -0
- package/src/ui/dialog.ts +3 -2
- package/src/ui/tooltips.ts +92 -0
- package/src/ui.d.ts +35 -0
- package/src/ui.ts +1 -0
- package/src/vite/graph.ts +11 -3
- package/src/vite/plugin.d.ts +7 -0
- package/src/vite/plugin.ts +10 -5
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* PLAN-11 T-1: Tooltips, one behavior for every tooltip of a component (glossary terms in a
|
|
3
|
+
* paragraph, icon buttons in a toolbar): one state slice and two timers however many triggers
|
|
4
|
+
* there are, instead of a tooltip() per trigger.
|
|
5
|
+
*
|
|
6
|
+
* Article.uses = { tips: tooltips({ trigger: '.term', tip: '.term-tip' }) }
|
|
7
|
+
*
|
|
8
|
+
* Each trigger names its tip with aria-describedby (the tip's id); the tips are `role="tooltip"
|
|
9
|
+
* popover="manual"` elements placed by CSS anchor positioning, as for tooltip(). One tip shows at
|
|
10
|
+
* a time. Moving from one trigger to another while a tip is shown switches at once (no second
|
|
11
|
+
* show delay), as tooltip groups do.
|
|
12
|
+
*
|
|
13
|
+
* Options: `trigger`, `tip` (required selectors matching every trigger / every tip),
|
|
14
|
+
* `showDelay` (500 ms), `hideDelay` (100 ms).
|
|
15
|
+
* State: { id (the tip of the trigger or tip last entered), open (the id of the tip shown),
|
|
16
|
+
* pending: null | 'show' | 'hide', hover, focus }. Actions: ENTER / LEAVE ({ via: 'hover' |
|
|
17
|
+
* 'focus', id }), SHOW / HIDE (the timers), ESCAPE, TOGGLED ({ id, open }). Timers
|
|
18
|
+
* '<key>.show' / '<key>.hide' as tooltip()'s. Needs makeTimerDriver() (tests: fake timers).
|
|
19
|
+
* Same rules as tooltip(): pointer and focus tracked apart, touch ignored, hovering the tip keeps
|
|
20
|
+
* it open (WCAG 1.4.13), Escape listened for only while a tip is shown or about to be.
|
|
21
|
+
*/
|
|
22
|
+
import {ABORT, defineBehavior, dropRepeats, xs} from '../index'
|
|
23
|
+
|
|
24
|
+
const mouse = (e: any) => e?.pointerType != 'touch'
|
|
25
|
+
const el = (e: any) => e?.ownerTarget || e?.currentTarget || e?.target
|
|
26
|
+
// the trigger's tip id (its aria-describedby: the first id when it lists several), or the tip's own
|
|
27
|
+
const tipOf = (e: any) => String(el(e)?.getAttribute?.('aria-describedby') || '').trim().split(/\s+/)[0] || null
|
|
28
|
+
const idOf = (e: any) => el(e)?.id || null
|
|
29
|
+
const at = (id: string) => `[id="${id.replace(/["\\]/g, '\\$&')}"]`
|
|
30
|
+
|
|
31
|
+
const base = /*#__PURE__*/ defineBehavior({
|
|
32
|
+
initialState: {id: null as null | string, open: null as null | string, pending: null as null | string, hover: false, focus: false},
|
|
33
|
+
timers: (s: any, o: any) => ({
|
|
34
|
+
show: s?.pending == 'show' && {after: o.showDelay ?? 500, action: 'SHOW'},
|
|
35
|
+
hide: s?.pending == 'hide' && {after: o.hideDelay ?? 100, action: 'HIDE'},
|
|
36
|
+
}),
|
|
37
|
+
intent: ({DOM, STATE}: any, {trigger, tip}: any) => ({
|
|
38
|
+
ENTER: xs.merge(
|
|
39
|
+
DOM.pointerenter(trigger).filter(mouse).map((e: any) => ({via: 'hover', id: tipOf(e)})),
|
|
40
|
+
DOM.pointerenter(tip).filter(mouse).map((e: any) => ({via: 'hover', id: idOf(e)})),
|
|
41
|
+
DOM.focus(trigger).map((e: any) => ({via: 'focus', id: tipOf(e)})),
|
|
42
|
+
).filter((x: any) => !!x.id),
|
|
43
|
+
LEAVE: xs.merge(
|
|
44
|
+
DOM.pointerleave(trigger).filter(mouse).map((e: any) => ({via: 'hover', id: tipOf(e)})),
|
|
45
|
+
DOM.pointerleave(tip).filter(mouse).map((e: any) => ({via: 'hover', id: idOf(e)})),
|
|
46
|
+
DOM.blur(trigger).map((e: any) => ({via: 'focus', id: tipOf(e)})),
|
|
47
|
+
).filter((x: any) => !!x.id),
|
|
48
|
+
ESCAPE: (STATE ? STATE.stream.map((s: any) => !!(s?.open || s?.pending)).compose(dropRepeats()) : xs.of(true))
|
|
49
|
+
.map((on: boolean) => (on ? DOM.keydown('document').key().filter((k: string) => k == 'Escape') : xs.never()))
|
|
50
|
+
.flatten(),
|
|
51
|
+
TOGGLED: DOM.toggle(tip).map((e: any) => ({id: idOf(e), open: e.newState == 'open'})).filter((x: any) => !!x.id),
|
|
52
|
+
}),
|
|
53
|
+
model: {
|
|
54
|
+
ENTER: {
|
|
55
|
+
STATE: (s: any, {via, id}: any) => {
|
|
56
|
+
const k = via == 'focus' ? 'focus' : 'hover'
|
|
57
|
+
// another trigger: it takes over (a tip already shown switches at once, in ELEMENT)
|
|
58
|
+
if (id != s.id) return {...s, id, hover: k == 'hover', focus: k == 'focus', pending: s.open ? null : 'show'}
|
|
59
|
+
const pending = s.open == id ? null : 'show'
|
|
60
|
+
return s[k] && s.pending == pending ? ABORT : {...s, [k]: true, pending}
|
|
61
|
+
},
|
|
62
|
+
// 7.0: outputs get the updated slice; "another trigger than before" reads the previous one
|
|
63
|
+
ELEMENT: (s: any, {id}: any, _n: any, p: any, _o: any, k: string) => {
|
|
64
|
+
const w = p?.previousState ? p.previousState[k] : s
|
|
65
|
+
return id != w.id && w.open && w.open != id ? [{hidePopover: at(w.open)}, {showPopover: at(id)}] : ABORT
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
LEAVE: (s: any, {via, id}: any) => {
|
|
69
|
+
if (id != s.id) return ABORT
|
|
70
|
+
const k = via == 'focus' ? 'focus' : 'hover'
|
|
71
|
+
const n = {...s, [k]: false}
|
|
72
|
+
const pending = n.hover || n.focus ? s.pending : s.open ? 'hide' : null
|
|
73
|
+
return !s[k] && s.pending == pending ? ABORT : {...n, pending}
|
|
74
|
+
},
|
|
75
|
+
SHOW: {
|
|
76
|
+
STATE: (s: any) => ({...s, pending: null}),
|
|
77
|
+
ELEMENT: (s: any) => (!s.id || s.open == s.id ? ABORT : s.open ? [{hidePopover: at(s.open)}, {showPopover: at(s.id)}] : {showPopover: at(s.id)}),
|
|
78
|
+
},
|
|
79
|
+
HIDE: {
|
|
80
|
+
STATE: (s: any) => ({...s, pending: null}),
|
|
81
|
+
ELEMENT: (s: any) => (s.open ? {hidePopover: at(s.open)} : ABORT),
|
|
82
|
+
},
|
|
83
|
+
ESCAPE: {
|
|
84
|
+
STATE: (s: any) => (s.open || s.pending ? {...s, pending: null} : ABORT),
|
|
85
|
+
ELEMENT: (s: any) => (s.open ? {hidePopover: at(s.open)} : ABORT),
|
|
86
|
+
},
|
|
87
|
+
TOGGLED: (s: any, {id, open}: any) => (open ? (s.open == id ? ABORT : {...s, open: id}) : s.open == id ? {...s, open: null} : ABORT),
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
/** Every tooltip of a component as one behavior: `uses = { tips: tooltips({ trigger: '.term', tip: '.term-tip' }) }`. */
|
|
92
|
+
export const tooltips = (options: any = {}): any => base({...options, id: null, open: null, pending: null, hover: false, focus: false})
|
package/src/ui.d.ts
CHANGED
|
@@ -75,6 +75,41 @@ export interface TooltipActions { ENTER: 'hover' | 'focus' | undefined; LEAVE: '
|
|
|
75
75
|
/** A tooltip: `uses = { tip: tooltip({ trigger: '.save', tip: '.save-tip' }) }`. Needs makeTimerDriver(). */
|
|
76
76
|
export function tooltip(options: TooltipOptions): Behavior<TooltipState, TooltipActions, {}, TooltipOptions>
|
|
77
77
|
|
|
78
|
+
// ── Tooltips (PLAN-11) ────────────────────────────────────────────────
|
|
79
|
+
export interface TooltipsState {
|
|
80
|
+
/** The tip id of the trigger (or tip) last entered */
|
|
81
|
+
id: string | null
|
|
82
|
+
/** The id of the tip shown, or null */
|
|
83
|
+
open: string | null
|
|
84
|
+
pending: null | 'show' | 'hide'
|
|
85
|
+
hover: boolean
|
|
86
|
+
focus: boolean
|
|
87
|
+
}
|
|
88
|
+
export interface TooltipsOptions {
|
|
89
|
+
/** Every trigger (a selector matching them all); each names its tip with aria-describedby */
|
|
90
|
+
trigger: BehaviorTarget
|
|
91
|
+
/** Every tip: role="tooltip" popover="manual" with an id, placed with CSS anchor positioning */
|
|
92
|
+
tip: BehaviorTarget
|
|
93
|
+
/** ms before a tip shows (default 500); moving to another trigger while one shows switches at once */
|
|
94
|
+
showDelay?: number
|
|
95
|
+
/** ms before it hides (default 100) */
|
|
96
|
+
hideDelay?: number
|
|
97
|
+
}
|
|
98
|
+
export interface TooltipsActions {
|
|
99
|
+
ENTER: { via: 'hover' | 'focus'; id: string }
|
|
100
|
+
LEAVE: { via: 'hover' | 'focus'; id: string }
|
|
101
|
+
SHOW: any
|
|
102
|
+
HIDE: any
|
|
103
|
+
ESCAPE: string
|
|
104
|
+
TOGGLED: { id: string; open: boolean }
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* PLAN-11 (6.7): every tooltip of a component as one behavior (one state slice, two timers):
|
|
108
|
+
* `uses = { tips: tooltips({ trigger: '.term', tip: '.term-tip' }) }`, each trigger with
|
|
109
|
+
* `aria-describedby` naming its tip's id. One tip shows at a time. Needs makeTimerDriver().
|
|
110
|
+
*/
|
|
111
|
+
export function tooltips(options: TooltipsOptions): Behavior<TooltipsState, TooltipsActions, {}, TooltipsOptions>
|
|
112
|
+
|
|
78
113
|
// ── Tabs ──────────────────────────────────────────────────────────────
|
|
79
114
|
export interface TabsState {
|
|
80
115
|
/** The ids' prefix (the key in `uses` unless the `id` option names it) */
|
package/src/ui.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
export {dialog} from './ui/dialog'
|
|
10
10
|
export {popover} from './ui/popover'
|
|
11
11
|
export {tooltip} from './ui/tooltip'
|
|
12
|
+
export {tooltips} from './ui/tooltips'
|
|
12
13
|
export {tabs, tabsAttrs} from './ui/tabs'
|
|
13
14
|
export {accordion, accordionAttrs} from './ui/accordion'
|
|
14
15
|
export {disclosure, disclosureAttrs} from './ui/disclosure'
|
package/src/vite/graph.ts
CHANGED
|
@@ -232,15 +232,23 @@ export function graphMiddleware(server: any, root: string, engine: Promise<LiveE
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
/**
|
|
236
|
-
export
|
|
235
|
+
/** The banner line when the project has no sygnal-check with the graph page (it used to print nothing). */
|
|
236
|
+
export const GRAPH_MISSING_LINE = ' ➜ Sygnal graph: needs sygnal-check 0.10.0 or later in this project (npm i -D sygnal-check)'
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Adds the page's URL under Vite's own when the dev server prints them, or, when the project's
|
|
240
|
+
* sygnal-check is missing or too old for the page (`available` false), a line saying what to install.
|
|
241
|
+
*/
|
|
242
|
+
export function printGraphUrl(server: any, available = true) {
|
|
237
243
|
const print = server?.printUrls
|
|
238
244
|
if (typeof print !== 'function') return
|
|
239
245
|
server.printUrls = function (this: any, ...args: any[]) {
|
|
240
246
|
const out = print.apply(this, args)
|
|
241
247
|
try {
|
|
248
|
+
const logger = server.config?.logger || console
|
|
242
249
|
const local = server.resolvedUrls?.local?.[0]
|
|
243
|
-
if (
|
|
250
|
+
if (!available) logger.info(GRAPH_MISSING_LINE)
|
|
251
|
+
else if (local) logger.info(` ➜ Sygnal graph: ${new URL(local).origin}${GRAPH_PATH}`)
|
|
244
252
|
} catch (_) {}
|
|
245
253
|
return out
|
|
246
254
|
}
|
package/src/vite/plugin.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export interface DiagnosticsPluginOptions {
|
|
|
12
12
|
* @default false
|
|
13
13
|
*/
|
|
14
14
|
strict?: boolean
|
|
15
|
+
/**
|
|
16
|
+
* 7.0 timing audit (SYG257, info): the dev snippet sets `globalThis.__SYGNAL_TIMING_AUDIT__ =
|
|
17
|
+
* true`, and each output sink that reads a top-level state field its action's STATE changed is
|
|
18
|
+
* reported (since 7.0 it gets the new value; 6.x gave it the old one). For migrating 6.x code.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
timingAudit?: boolean
|
|
15
22
|
/** Diagnostic codes to drop, e.g. ['SYG105'] (runtime and static) */
|
|
16
23
|
ignore?: string[]
|
|
17
24
|
}
|
package/src/vite/plugin.ts
CHANGED
|
@@ -130,7 +130,8 @@
|
|
|
130
130
|
* skipped silently when missing; a sygnal-check without the page keeps the checker as in 5)
|
|
131
131
|
* builds it with createLiveProject on start and after each change: one build gives the page,
|
|
132
132
|
* the check overlay / console findings of 5, and the component stamps. Its URL is printed
|
|
133
|
-
* under Vite's ("➜ Sygnal graph: http://localhost:5173/__sygnal/graph"
|
|
133
|
+
* under Vite's ("➜ Sygnal graph: http://localhost:5173/__sygnal/graph"; without a sygnal-check
|
|
134
|
+
* 0.10.0+ in the project, a line saying so instead). The modules of the
|
|
134
135
|
* scanned files get a tail setting a non-enumerable `__sygnalKey` (the static 'file#name'
|
|
135
136
|
* key, D521) on each top-level component function, which the runtime inspect() reports as
|
|
136
137
|
* `key`; with DevTools on, the dev entries also import 'virtual:sygnal/graph'
|
|
@@ -191,6 +192,8 @@ export interface DiagnosticsPluginOptions {
|
|
|
191
192
|
mode?: DiagnosticsMode
|
|
192
193
|
/** Strict (canonical-form, SYG5xx) runtime checks: sets globalThis.__SYGNAL_STRICT__. @default false */
|
|
193
194
|
strict?: boolean
|
|
195
|
+
/** 7.0 timing audit (SYG257, info): sets globalThis.__SYGNAL_TIMING_AUDIT__. @default false */
|
|
196
|
+
timingAudit?: boolean
|
|
194
197
|
/** Diagnostic codes to drop, e.g. ['SYG105'] */
|
|
195
198
|
ignore?: string[]
|
|
196
199
|
}
|
|
@@ -343,7 +346,7 @@ export default function sygnal(options: SygnalPluginOptions = {}) {
|
|
|
343
346
|
// Files whose `import ... from 'sygnal'` resolves to the run() wrapper
|
|
344
347
|
const runtimeImporters = new Set<string>()
|
|
345
348
|
// Statements run before the app starts: dev flag (+ strict flag)
|
|
346
|
-
const flags = DEV_FLAG + (diagnostics.strict ? STRICT_FLAG : '')
|
|
349
|
+
const flags = DEV_FLAG + (diagnostics.strict ? STRICT_FLAG : '') + (diagnostics.timingAudit ? AUDIT_FLAG : '')
|
|
347
350
|
const devImports = `import 'sygnal/diagnostics';import '${DEV_CLIENT}';`
|
|
348
351
|
// D77: the DevTools bridge, dev only. First, so the diagnostics entry finds it.
|
|
349
352
|
// E-1: the MCP endpoint needs the bridge, so `mcp` turns it on
|
|
@@ -535,7 +538,7 @@ export default function sygnal(options: SygnalPluginOptions = {}) {
|
|
|
535
538
|
// W-2 (D543): the page and its stream, behind the MCP endpoint's guard; its URL in the banner
|
|
536
539
|
if (graphOn && server?.middlewares) {
|
|
537
540
|
server.middlewares.use(graphMiddleware(server, root, engine))
|
|
538
|
-
|
|
541
|
+
printGraphUrl(server, graphAvailable(root))
|
|
539
542
|
}
|
|
540
543
|
},
|
|
541
544
|
|
|
@@ -790,7 +793,7 @@ function viteMajor(ctx: any, root: string): number {
|
|
|
790
793
|
return Infinity
|
|
791
794
|
}
|
|
792
795
|
|
|
793
|
-
interface NormalizedDiagnostics { mode: DiagnosticsMode, strict: boolean, ignore: string[] }
|
|
796
|
+
interface NormalizedDiagnostics { mode: DiagnosticsMode, strict: boolean, timingAudit: boolean, ignore: string[] }
|
|
794
797
|
|
|
795
798
|
const MODES: DiagnosticsMode[] = ['off', 'collect', 'warn', 'error']
|
|
796
799
|
|
|
@@ -800,7 +803,7 @@ function normalizeDiagnostics(value: SygnalPluginOptions['diagnostics']): Normal
|
|
|
800
803
|
if (!MODES.includes(mode)) {
|
|
801
804
|
throw new Error(`[vite-plugin-sygnal] diagnostics mode must be one of ${MODES.map(m => `'${m}'`).join(', ')}; got ${JSON.stringify(mode)}`)
|
|
802
805
|
}
|
|
803
|
-
return { mode, strict: !!o.strict, ignore: Array.isArray(o.ignore) ? o.ignore.map(String) : [] }
|
|
806
|
+
return { mode, strict: !!o.strict, timingAudit: !!o.timingAudit, ignore: Array.isArray(o.ignore) ? o.ignore.map(String) : [] }
|
|
804
807
|
}
|
|
805
808
|
|
|
806
809
|
/** Module id without a query or hash. */
|
|
@@ -1155,6 +1158,8 @@ function startChecker(server: any, root: string, mod: any, setup: CheckSetup, op
|
|
|
1155
1158
|
|
|
1156
1159
|
const DEV_FLAG = 'if (globalThis.__SYGNAL_DEV__ === undefined) globalThis.__SYGNAL_DEV__ = true;'
|
|
1157
1160
|
const STRICT_FLAG = 'if (globalThis.__SYGNAL_STRICT__ === undefined) globalThis.__SYGNAL_STRICT__ = true;'
|
|
1161
|
+
// 7.0: the opt-in timing audit (SYG257, 'sygnal/diagnostics' checks/timingAudit.ts)
|
|
1162
|
+
const AUDIT_FLAG = 'if (globalThis.__SYGNAL_TIMING_AUDIT__ === undefined) globalThis.__SYGNAL_TIMING_AUDIT__ = true;'
|
|
1158
1163
|
|
|
1159
1164
|
// A top-level (column 0) run(Component, ...) statement: bare, or declaring a
|
|
1160
1165
|
// new binding. Assignments to existing variables, nested calls and indented
|