@zerotal/flow 1.6.2 → 1.7.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 +20 -1
- package/api-surface.md +1125 -0
- package/package.json +6 -5
- package/src/Component.ts +13 -2
- package/src/client/bridge.ts +15 -1
- package/src/dehydrate.ts +2 -2
- package/src/durable.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,7 +9,26 @@ follows SemVer strictly: anything importable without an `@internal` marker keeps
|
|
|
9
9
|
shape for the rest of the 1.x line, and `api-surface.md` is diffed by CI on every
|
|
10
10
|
change.
|
|
11
11
|
|
|
12
|
-
## [
|
|
12
|
+
## [1.7.0] — 2026-08-16
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **SPA navigation no longer orphans the outgoing page's snapshot.** The swap removed the
|
|
17
|
+
first `[id^="flow-state-"]` in document order, but a page-level snapshot is a direct child
|
|
18
|
+
of `<body>` while a child island's sits inside the body content — so on any page with an
|
|
19
|
+
island it removed the island's script and left the page's behind. Ids are random per
|
|
20
|
+
request, so the leftovers accumulated one per navigation for as long as the tab stayed
|
|
21
|
+
open. Now scoped to `body > script[id^="flow-state-"]`, and every match is removed, so a
|
|
22
|
+
session that has already leaked cleans itself up on the next navigation.
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
|
|
26
|
+
- **`Component._skipMount`**, an `@internal` field that was written by `hydrate()` and
|
|
27
|
+
`restoreDurable()` and read by nothing. Mount-skipping is structural — the router branches
|
|
28
|
+
between `onHydrate()` and `onMount()` — and wiring the flag up would have been wrong:
|
|
29
|
+
`$refresh` and `$mount` deliberately re-run `onMount()` on a hydrated page. An inert flag
|
|
30
|
+
that reads as load-bearing is worse than none, so it is gone and the guarantee is pinned by
|
|
31
|
+
a test instead: mount runs exactly once across an initial render and any number of actions.
|
|
13
32
|
|
|
14
33
|
## [1.6.0] — 2026-08-15
|
|
15
34
|
|
package/api-surface.md
ADDED
|
@@ -0,0 +1,1125 @@
|
|
|
1
|
+
# @zerotal/flow — public API surface
|
|
2
|
+
|
|
3
|
+
<!-- AUTO-GENERATED by scripts/api-surface.ts. Do not edit by hand.
|
|
4
|
+
Run `bun run api:surface` to regenerate after an intentional API change. -->
|
|
5
|
+
|
|
6
|
+
## . `(./src/index.ts)`
|
|
7
|
+
|
|
8
|
+
class Component = {
|
|
9
|
+
new (): Component
|
|
10
|
+
static durable?: boolean | { ttl?: string; scope?: 'user' | 'session';}
|
|
11
|
+
static readonly __isFlowPage: true
|
|
12
|
+
static using: Compose
|
|
13
|
+
$refresh: () => void
|
|
14
|
+
$set: (key: string, value: unknown) => void
|
|
15
|
+
_applyClientUpdate: (key: string, value: unknown, arrayKey?: string) => Promise<void>
|
|
16
|
+
_buildSchema: (builders: Map<string, ValidateBuilder>) => Schema
|
|
17
|
+
_childIds: string[]
|
|
18
|
+
_clearDurable: boolean
|
|
19
|
+
_clientScripts: string[]
|
|
20
|
+
_downloads: { filename: string; content: string; mime: string;}[]
|
|
21
|
+
_drainEffects: () => FlowEffects
|
|
22
|
+
_emitUpdateHook: (base: 'onUpdating' | 'onUpdated', prop: string, value: unknown, key?: string) => Promise<void>
|
|
23
|
+
_errors: Record<string, string[]>
|
|
24
|
+
_events: { name: string; data: Record<string, unknown>; to?: string; self?: boolean;}[]
|
|
25
|
+
_exposedData: () => Record<string, unknown>
|
|
26
|
+
_flashes: FlashMessage[]
|
|
27
|
+
_flowId: string
|
|
28
|
+
_flowPath: string
|
|
29
|
+
_flowSlots: Record<string, string>
|
|
30
|
+
_isHydrated: boolean
|
|
31
|
+
_prevChildIds: string[]
|
|
32
|
+
_redirectStatus: number | null
|
|
33
|
+
_redirectUrl: string | null
|
|
34
|
+
_shouldRefresh: boolean
|
|
35
|
+
_streamSender: ((ref: string, content: string, replace: boolean) => void) | null
|
|
36
|
+
_taskSignal: AbortSignal | null
|
|
37
|
+
_titleValue: string | null
|
|
38
|
+
_validateField: (field: string) => Promise<void>
|
|
39
|
+
addError: (field: string, message: string) => void
|
|
40
|
+
bind: (key: string, optionValue?: string) => Record<string, unknown>
|
|
41
|
+
cancelled: boolean
|
|
42
|
+
child: <C extends Component>(ChildClass: new () => C, opts?: { key?: string | number; props?: Partial<C>; lazy?: boolean; defer?: boolean; stream?: boolean; slots?: Record<string, string>;}) => Promise<HtmlNode>
|
|
43
|
+
clearDurable: () => void
|
|
44
|
+
client: (script: string) => void
|
|
45
|
+
currentUrl: (_options?: CurrentUrlOptions) => string
|
|
46
|
+
dispatch: <K extends string>(name: K, ...args: K extends EventName ? EventArgs<FlowEvents[K]> : [payload?: Record<string, unknown>]) => void
|
|
47
|
+
dispatchSelf: <K extends string>(name: K, ...args: K extends EventName ? EventArgs<FlowEvents[K]> : [payload?: Record<string, unknown>]) => void
|
|
48
|
+
dispatchTo: <K extends string>(component: string, name: K, ...args: K extends EventName ? EventArgs<FlowEvents[K]> : [payload?: Record<string, unknown>]) => void
|
|
49
|
+
download: (filename: string, content: string | Uint8Array, mime?: string) => void
|
|
50
|
+
errors: ErrorsProxy
|
|
51
|
+
flash: (message: string, optionsOrLevel?: FlashLevel | FlashOptions) => FlashBuilder
|
|
52
|
+
hasSlot: (name?: string) => boolean
|
|
53
|
+
layout: (page: HtmlNode) => HtmlNode | Promise<HtmlNode>
|
|
54
|
+
navigateCurrent: (_options?: CurrentUrlOptions) => Promise<void>
|
|
55
|
+
onBoot: (_ctx?: HttpContext) => Promise<void>
|
|
56
|
+
onDehydrate: () => Promise<void>
|
|
57
|
+
onError: (error: Error) => Promise<void>
|
|
58
|
+
onHydrate: () => Promise<void>
|
|
59
|
+
onMount: (_ctx?: HttpContext) => Promise<void>
|
|
60
|
+
onRendered: (_html: string) => Promise<void>
|
|
61
|
+
onRendering: () => Promise<void>
|
|
62
|
+
onUpdate: () => Promise<void>
|
|
63
|
+
onUpdated: (_prop: string, _value: unknown, _key?: string) => Promise<void>
|
|
64
|
+
onUpdating: (_prop: string, _value: unknown, _key?: string) => Promise<void>
|
|
65
|
+
placeholder: () => HtmlNode
|
|
66
|
+
redirect: (url: string, status?: number) => RedirectFlash
|
|
67
|
+
redirectIntended: (fallback?: string, status?: number) => RedirectFlash
|
|
68
|
+
redirectRoute: <N extends RouteTarget>(name: N, params?: RouteParamsArg<N>, status?: number) => RedirectFlash
|
|
69
|
+
refresh: () => Promise<void>
|
|
70
|
+
render: () => Promise<HtmlNode>
|
|
71
|
+
resetValidation: (field?: string) => void
|
|
72
|
+
signal: AbortSignal
|
|
73
|
+
slot: (name?: string) => HtmlNode
|
|
74
|
+
stream: (ref: string, content: string, opts?: { replace?: boolean;}) => void
|
|
75
|
+
title: { (): string; (value: string): void;}
|
|
76
|
+
validate: (rulesOrForm?: ValidationRules | { __isFlowForm: true; _validateToErrors(): Record<string, string[]>;}) => Promise<void>
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class ErrorField = {
|
|
80
|
+
new (field: string, messages: string[]): ErrorField
|
|
81
|
+
readonly __field: string
|
|
82
|
+
readonly __isErrorField: true
|
|
83
|
+
readonly __value: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class FlowActionHandled = {
|
|
87
|
+
new (component: string, action: string, durationMs: number, ok: boolean, ip: string | null, ctx: object | undefined): FlowActionHandled
|
|
88
|
+
readonly action: string
|
|
89
|
+
readonly component: string
|
|
90
|
+
readonly ctx: object | undefined
|
|
91
|
+
readonly durationMs: number
|
|
92
|
+
readonly ip: string | null
|
|
93
|
+
readonly ok: boolean
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
class FlowProvider = {
|
|
97
|
+
new (app: Application): FlowProvider
|
|
98
|
+
static dependsOn?: (new (app: Application) => ServiceProvider)[]
|
|
99
|
+
static environments: AppEnvironment[]
|
|
100
|
+
static persistMiddleware: (...middleware: (string | MiddlewareClass)[]) => void
|
|
101
|
+
static persistentMiddleware: (string | MiddlewareClass)[]
|
|
102
|
+
static priority?: number
|
|
103
|
+
static provides?: readonly (keyof ContainerBindings)[]
|
|
104
|
+
static registerSynth: (synth: Synth) => void
|
|
105
|
+
devProcesses: () => DevProcessDefinition[]
|
|
106
|
+
doctorChecks: () => DoctorCheck[]
|
|
107
|
+
onBooted: () => Promise<void>
|
|
108
|
+
onBooting: () => Promise<void>
|
|
109
|
+
onRegister: () => void
|
|
110
|
+
onRequestProcessed: (_ctx: HttpContext) => Promise<void>
|
|
111
|
+
onRequestReceived: (_ctx: HttpContext) => Promise<void>
|
|
112
|
+
onResponseSent: (_ctx: HttpContext) => Promise<void>
|
|
113
|
+
onStarted: () => Promise<void>
|
|
114
|
+
onStarting: () => Promise<void>
|
|
115
|
+
onStopped: () => Promise<void>
|
|
116
|
+
onStopping: () => Promise<void>
|
|
117
|
+
replContext: () => Record<string, unknown>
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class Form = {
|
|
121
|
+
new (): Form
|
|
122
|
+
_validateToErrors: () => Record<string, string[]>
|
|
123
|
+
data: () => Record<string, unknown>
|
|
124
|
+
fill: (values: Record<string, unknown>) => Form
|
|
125
|
+
readonly __isFlowForm: true
|
|
126
|
+
reset: (...fields: string[]) => Form
|
|
127
|
+
rules: (_v: RuleBuilder) => Record<string, FieldRule>
|
|
128
|
+
validate: () => Record<string, unknown>
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
class Layout = {
|
|
132
|
+
new (): Layout
|
|
133
|
+
static head?: string
|
|
134
|
+
render: (slot: HtmlNode) => HtmlNode | Promise<HtmlNode>
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class TemporaryUploadedFile = {
|
|
138
|
+
new (d: TufData): TemporaryUploadedFile
|
|
139
|
+
static fromSignedRef: (ref: UploadRef) => TemporaryUploadedFile | null
|
|
140
|
+
static fromTrustedRef: (data: TufData) => TemporaryUploadedFile
|
|
141
|
+
bytes: () => Promise<Uint8Array>
|
|
142
|
+
extension: () => string
|
|
143
|
+
isImage: () => boolean
|
|
144
|
+
name: string
|
|
145
|
+
readonly mime: string
|
|
146
|
+
readonly originalName: string
|
|
147
|
+
readonly size: number
|
|
148
|
+
readonly tempDisk?: string | undefined
|
|
149
|
+
readonly tmpPath: string
|
|
150
|
+
store: (directory: string, diskName?: string, filename?: string) => Promise<string>
|
|
151
|
+
temporaryUrl: (ttlSeconds?: number) => Promise<string>
|
|
152
|
+
toRef: () => TufData
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class ValidationError = {
|
|
156
|
+
new (errors: Record<string, string[]>): ValidationError
|
|
157
|
+
readonly code: string
|
|
158
|
+
readonly context?: Record<string, unknown> | undefined
|
|
159
|
+
readonly errors: Record<string, string[]>
|
|
160
|
+
readonly status: number
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
class WebSocketConnected = {
|
|
164
|
+
new (url: string): WebSocketConnected
|
|
165
|
+
readonly url: string
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class WebSocketDisconnected = {
|
|
169
|
+
new (url: string): WebSocketDisconnected
|
|
170
|
+
readonly url: string
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const BLOCKED_URL = 'about:blank'
|
|
174
|
+
|
|
175
|
+
const DEFAULT_PERSISTENT_MIDDLEWARE = (string | MiddlewareClass)[]
|
|
176
|
+
|
|
177
|
+
const locked = (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
178
|
+
|
|
179
|
+
const modelable = (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
180
|
+
|
|
181
|
+
const reactive = (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
182
|
+
|
|
183
|
+
const transient = (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
184
|
+
|
|
185
|
+
const URL_ATTRIBUTES = ReadonlySet<string>
|
|
186
|
+
|
|
187
|
+
function Accordion = (props: AccordionProps) => HtmlNode
|
|
188
|
+
|
|
189
|
+
function Alert = (props: AlertProps) => HtmlNode
|
|
190
|
+
|
|
191
|
+
function Calendar = (props: CalendarProps) => HtmlNode
|
|
192
|
+
|
|
193
|
+
function Checkbox = (props: CheckboxProps) => HtmlNode
|
|
194
|
+
|
|
195
|
+
function Combobox = (props: ComboboxProps) => HtmlNode
|
|
196
|
+
|
|
197
|
+
function computed = <This, Return>(getter: (this: This) => Return, context: ClassGetterDecoratorContext<This, Return>) => (this: This) => Return
|
|
198
|
+
|
|
199
|
+
function defineStore = (initial: Record<string, unknown>) => void
|
|
200
|
+
|
|
201
|
+
function Description = (props: DescriptionProps) => HtmlNode
|
|
202
|
+
|
|
203
|
+
function Disclosure = (props: DisclosureProps) => HtmlNode
|
|
204
|
+
|
|
205
|
+
function Drawer = (props: DrawerProps) => HtmlNode
|
|
206
|
+
|
|
207
|
+
function Dropdown = (props: DropdownProps) => HtmlNode
|
|
208
|
+
|
|
209
|
+
function ErrorBoundary = (props: ErrorBoundaryProps) => HtmlNode
|
|
210
|
+
|
|
211
|
+
function ErrorMessage = (props: ErrorProps) => HtmlNode
|
|
212
|
+
|
|
213
|
+
function Errors = (props?: ErrorsProps) => HtmlNode
|
|
214
|
+
|
|
215
|
+
function expose = (_value: unknown, context: ExposeContext) => void
|
|
216
|
+
|
|
217
|
+
function Field = (props: FieldProps) => HtmlNode
|
|
218
|
+
|
|
219
|
+
function Fieldset = (props: FieldsetProps) => HtmlNode
|
|
220
|
+
|
|
221
|
+
function FileUpload = (props: FileUploadProps) => HtmlNode
|
|
222
|
+
|
|
223
|
+
function FileUploads = <TBase extends AbstractComponentCtor>(Base: TBase) => ((abstract new (...args: any[]) => WithUploads) & { prototype: FileUploads<any>.WithUploads;}) & TBase
|
|
224
|
+
|
|
225
|
+
function Flash = (props?: FlashProps) => HtmlNode
|
|
226
|
+
|
|
227
|
+
function flow = <T>(target: T) => FlowChain<T>
|
|
228
|
+
|
|
229
|
+
function flowActiveConnections = () => number
|
|
230
|
+
|
|
231
|
+
function FlowConfig = (options?: Partial<FlowConfigShape>) => FlowConfigShape
|
|
232
|
+
|
|
233
|
+
function flowConnections = () => FlowConnection[]
|
|
234
|
+
|
|
235
|
+
function For = <T>(props: ForProps<T>) => HtmlNode
|
|
236
|
+
|
|
237
|
+
function getDurableStore = () => DurableStore
|
|
238
|
+
|
|
239
|
+
function getSharedStore = () => SharedStore
|
|
240
|
+
|
|
241
|
+
function Head = (props: { children?: unknown;}) => HtmlNode
|
|
242
|
+
|
|
243
|
+
function InfiniteScroll = (props: InfiniteScrollProps) => HtmlNode
|
|
244
|
+
|
|
245
|
+
function isSafeUrl = (url: string) => boolean
|
|
246
|
+
|
|
247
|
+
function jsLiteral = (value: unknown) => string
|
|
248
|
+
|
|
249
|
+
function Label = (props: LabelProps) => HtmlNode
|
|
250
|
+
|
|
251
|
+
function Legend = (props: LegendProps) => HtmlNode
|
|
252
|
+
|
|
253
|
+
function Link = (props: LinkProps & { children?: unknown;}) => HtmlNode
|
|
254
|
+
|
|
255
|
+
function Listbox = (props: ListboxProps) => HtmlNode
|
|
256
|
+
|
|
257
|
+
function Loading = (props: LoadingProps) => HtmlNode
|
|
258
|
+
|
|
259
|
+
function Modal = (props: ModalProps) => HtmlNode
|
|
260
|
+
|
|
261
|
+
function on = (eventName: LooseEventName) => (fn: unknown, context: ClassMethodDecoratorContext) => void
|
|
262
|
+
|
|
263
|
+
function Pager = (props: PagerProps) => HtmlNode
|
|
264
|
+
|
|
265
|
+
function paginate = <T>(items: T[], page?: number, perPage?: number) => Paginator<T>
|
|
266
|
+
|
|
267
|
+
function Pagination = <TBase extends AbstractComponentCtor>(Base: TBase) => ((abstract new (...args: any[]) => Paginated) & { prototype: Pagination<any>.Paginated;}) & TBase
|
|
268
|
+
|
|
269
|
+
function param = { (value: unknown, context: ClassFieldDecoratorContext): void; (source?: string | ParamModel): ParamDecorator;}
|
|
270
|
+
|
|
271
|
+
function Persist = (props: { name: string; children?: unknown;}) => HtmlNode
|
|
272
|
+
|
|
273
|
+
function Popover = (props: PopoverProps) => HtmlNode
|
|
274
|
+
|
|
275
|
+
function presence = (channel: PresenceChannel) => (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
276
|
+
|
|
277
|
+
function RadioGroup = (props: RadioGroupProps) => HtmlNode
|
|
278
|
+
|
|
279
|
+
function registerComponent = (PageClass: typeof Component, path?: string) => void
|
|
280
|
+
|
|
281
|
+
function registerFlowEvent = <K extends EventName>(name: K, guard: (payload: unknown) => payload is FlowEvents[K]) => void
|
|
282
|
+
|
|
283
|
+
function registerFlowModel = (name: string, ModelClass: typeof BaseModel) => void
|
|
284
|
+
|
|
285
|
+
function registerForm = (FormClass: new () => Form) => void
|
|
286
|
+
|
|
287
|
+
function registerSynth = (synth: Synth) => void
|
|
288
|
+
|
|
289
|
+
function renderless = (_fn: unknown, context: ClassMethodDecoratorContext) => void
|
|
290
|
+
|
|
291
|
+
function sanitizeUrl = (url: string) => string
|
|
292
|
+
|
|
293
|
+
function SectionContent = (props: SectionContentProps) => HtmlNode
|
|
294
|
+
|
|
295
|
+
function SectionOutlet = (props: SectionOutletProps) => HtmlNode
|
|
296
|
+
|
|
297
|
+
function Select = (props: SelectProps) => HtmlNode
|
|
298
|
+
|
|
299
|
+
function session = { (value: unknown, context: ClassFieldDecoratorContext): void; (opts?: SessionOptions): SessionDecorator;}
|
|
300
|
+
|
|
301
|
+
function setDurableStore = (store: DurableStore) => void
|
|
302
|
+
|
|
303
|
+
function setSharedStore = (store: SharedStore) => void
|
|
304
|
+
|
|
305
|
+
function shared = (channel: SharedChannel) => (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
306
|
+
|
|
307
|
+
function Skeleton = (props: SkeletonProps) => HtmlNode
|
|
308
|
+
|
|
309
|
+
function Slider = (props: SliderProps) => HtmlNode
|
|
310
|
+
|
|
311
|
+
function Switch = (props: SwitchProps) => HtmlNode
|
|
312
|
+
|
|
313
|
+
function Table = <T extends Record<string, unknown>>(props: TableProps<T>) => HtmlNode
|
|
314
|
+
|
|
315
|
+
function Tabs = (props: TabsProps) => HtmlNode
|
|
316
|
+
|
|
317
|
+
function task = (_fn: unknown, context: ClassMethodDecoratorContext) => void
|
|
318
|
+
|
|
319
|
+
function Title = (props: { children?: unknown;}) => HtmlNode
|
|
320
|
+
|
|
321
|
+
function ToggleGroup = (props: ToggleGroupProps) => HtmlNode
|
|
322
|
+
|
|
323
|
+
function Tooltip = (props: TooltipProps) => HtmlNode
|
|
324
|
+
|
|
325
|
+
function url = { (value: unknown, context: ClassFieldDecoratorContext): void; (opts?: UrlOptions): UrlDecorator;}
|
|
326
|
+
|
|
327
|
+
function validate = (build: ValidateBuilder) => (value: unknown, context: ClassFieldDecoratorContext) => void
|
|
328
|
+
|
|
329
|
+
function Virtualize = <T>(props: VirtualizeProps<T>) => HtmlNode
|
|
330
|
+
|
|
331
|
+
interface AccordionItem = {
|
|
332
|
+
content: unknown
|
|
333
|
+
label: unknown
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
interface AccordionProps = {
|
|
337
|
+
[key: string]: unknown
|
|
338
|
+
buttonClass?: string
|
|
339
|
+
class?: string
|
|
340
|
+
defaultIndex?: number
|
|
341
|
+
itemClass?: string
|
|
342
|
+
items: AccordionItem[]
|
|
343
|
+
multiple?: boolean
|
|
344
|
+
panelClass?: string
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
interface AlertProps = {
|
|
348
|
+
[key: string]: unknown
|
|
349
|
+
children?: unknown
|
|
350
|
+
class?: string
|
|
351
|
+
dismissible?: boolean
|
|
352
|
+
title?: unknown
|
|
353
|
+
variant?: 'success' | 'error' | 'warning' | 'info'
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
interface CalendarProps = {
|
|
357
|
+
[key: string]: unknown
|
|
358
|
+
bind?: unknown
|
|
359
|
+
class?: string
|
|
360
|
+
dayClass?: string
|
|
361
|
+
gridClass?: string
|
|
362
|
+
headerClass?: string
|
|
363
|
+
max?: string
|
|
364
|
+
min?: string
|
|
365
|
+
month?: string
|
|
366
|
+
name?: string
|
|
367
|
+
navClass?: string
|
|
368
|
+
sundayFirst?: boolean
|
|
369
|
+
weekdayClass?: string
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
interface CallFrame = {
|
|
373
|
+
args: unknown[]
|
|
374
|
+
component: string
|
|
375
|
+
method: string
|
|
376
|
+
snapshot: Snapshot
|
|
377
|
+
type: 'call'
|
|
378
|
+
updates: Record<string, unknown>
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
interface CheckboxProps = {
|
|
382
|
+
[key: string]: unknown
|
|
383
|
+
bind: unknown
|
|
384
|
+
children?: unknown
|
|
385
|
+
class?: string
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
interface ChildMemo = {
|
|
389
|
+
id: string
|
|
390
|
+
key: string
|
|
391
|
+
name: string
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
interface ComboboxOption = {
|
|
395
|
+
label: string
|
|
396
|
+
value: string | number
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
interface ComboboxProps = {
|
|
400
|
+
[key: string]: unknown
|
|
401
|
+
bind?: unknown
|
|
402
|
+
class?: string
|
|
403
|
+
inputClass?: string
|
|
404
|
+
name?: string
|
|
405
|
+
optionClass?: string
|
|
406
|
+
options: ComboboxOption[]
|
|
407
|
+
optionsClass?: string
|
|
408
|
+
placeholder?: string
|
|
409
|
+
query?: unknown
|
|
410
|
+
queryName?: string
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
interface Compose = {
|
|
414
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor, D extends Constructor, E extends Constructor, F extends Constructor, G extends Constructor, H extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D, e: (base: D) => E, f: (base: E) => F, g: (base: F) => G, h: (base: G) => H): H
|
|
415
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor, D extends Constructor, E extends Constructor, F extends Constructor, G extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D, e: (base: D) => E, f: (base: E) => F, g: (base: F) => G): G
|
|
416
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor, D extends Constructor, E extends Constructor, F extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D, e: (base: D) => E, f: (base: E) => F): F
|
|
417
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor, D extends Constructor, E extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D, e: (base: D) => E): E
|
|
418
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor, D extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D): D
|
|
419
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B, c: (base: B) => C): C
|
|
420
|
+
<TBase extends Constructor, A extends Constructor, B extends Constructor>(this: TBase, a: (base: TBase) => A, b: (base: A) => B): B
|
|
421
|
+
<TBase extends Constructor, A extends Constructor>(this: TBase, a: (base: TBase) => A): A
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
interface DescriptionProps = {
|
|
425
|
+
[key: string]: unknown
|
|
426
|
+
children?: unknown
|
|
427
|
+
class?: string
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
interface DisclosureProps = {
|
|
431
|
+
[key: string]: unknown
|
|
432
|
+
buttonClass?: string
|
|
433
|
+
children?: unknown
|
|
434
|
+
class?: string
|
|
435
|
+
defaultOpen?: boolean
|
|
436
|
+
label?: unknown
|
|
437
|
+
panelClass?: string
|
|
438
|
+
trigger?: unknown
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
interface DownloadFrame = {
|
|
442
|
+
content: string
|
|
443
|
+
filename: string
|
|
444
|
+
mime: string
|
|
445
|
+
type: 'download'
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
interface DrawerProps = {
|
|
449
|
+
[key: string]: unknown
|
|
450
|
+
children?: unknown
|
|
451
|
+
class?: string
|
|
452
|
+
closable?: boolean
|
|
453
|
+
name?: string
|
|
454
|
+
onClose?: unknown
|
|
455
|
+
show?: unknown
|
|
456
|
+
side?: 'left' | 'right' | 'top' | 'bottom'
|
|
457
|
+
title?: unknown
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
interface DropdownProps = {
|
|
461
|
+
[key: string]: unknown
|
|
462
|
+
align?: 'left' | 'right'
|
|
463
|
+
children?: unknown
|
|
464
|
+
class?: string
|
|
465
|
+
label?: unknown
|
|
466
|
+
panelClass?: string
|
|
467
|
+
trigger?: unknown
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
interface DurableStore = {
|
|
471
|
+
delete: (key: string) => Promise<void> | void
|
|
472
|
+
get: (key: string) => Promise<Snapshot | undefined> | Snapshot | undefined
|
|
473
|
+
set: (key: string, value: Snapshot, ttlMs?: number) => Promise<void> | void
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
interface ErrorBoundaryProps = {
|
|
477
|
+
[key: string]: unknown
|
|
478
|
+
children?: unknown
|
|
479
|
+
class?: string
|
|
480
|
+
fallback?: HtmlNode | ((error: unknown) => HtmlNode)
|
|
481
|
+
onError?: (error: unknown) => void
|
|
482
|
+
tag?: string
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
interface ErrorFrame = {
|
|
486
|
+
action?: string
|
|
487
|
+
component: string
|
|
488
|
+
message: string
|
|
489
|
+
name?: string
|
|
490
|
+
stack?: string
|
|
491
|
+
type: 'error'
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
interface ErrorProps = {
|
|
495
|
+
[key: string]: unknown
|
|
496
|
+
class?: string
|
|
497
|
+
for?: unknown
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
interface ErrorsProps = {
|
|
501
|
+
[key: string]: unknown
|
|
502
|
+
class?: string
|
|
503
|
+
only?: string | string[]
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
interface ErrorsProxy = {
|
|
507
|
+
[key: string]: ErrorField | ((...args: never[]) => unknown)
|
|
508
|
+
add: { (field: string, message: string): void; (errors: Record<string, string | string[]>): void;}
|
|
509
|
+
any: () => boolean
|
|
510
|
+
clear: (field?: string) => void
|
|
511
|
+
has: (field: string) => boolean
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
interface EventFrame = {
|
|
515
|
+
data: Record<string, unknown>
|
|
516
|
+
name: string
|
|
517
|
+
type: 'event'
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
interface FieldProps = {
|
|
521
|
+
[key: string]: unknown
|
|
522
|
+
children?: unknown
|
|
523
|
+
class?: string
|
|
524
|
+
description?: unknown
|
|
525
|
+
error?: unknown
|
|
526
|
+
label?: unknown
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
interface FieldsetProps = {
|
|
530
|
+
[key: string]: unknown
|
|
531
|
+
children?: unknown
|
|
532
|
+
class?: string
|
|
533
|
+
disabled?: boolean
|
|
534
|
+
legend?: unknown
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
interface FileUploadProps = {
|
|
538
|
+
[key: string]: unknown
|
|
539
|
+
accept?: string
|
|
540
|
+
bind: unknown
|
|
541
|
+
children?: unknown
|
|
542
|
+
class?: string
|
|
543
|
+
label?: string
|
|
544
|
+
multiple?: boolean
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
interface FlashAction = {
|
|
548
|
+
args?: unknown[]
|
|
549
|
+
color?: string
|
|
550
|
+
label: string
|
|
551
|
+
method: string
|
|
552
|
+
uppercase?: boolean
|
|
553
|
+
variant?: FlashActionVariant
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
interface FlashActionStyle = {
|
|
557
|
+
color?: string
|
|
558
|
+
uppercase?: boolean
|
|
559
|
+
variant?: FlashActionVariant
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
interface FlashBuilder = {
|
|
563
|
+
action: (label: string, method: string, args?: unknown[], style?: string | FlashActionStyle) => FlashBuilder
|
|
564
|
+
dismissible: (value?: boolean) => FlashBuilder
|
|
565
|
+
duration: (ms: number) => FlashBuilder
|
|
566
|
+
error: () => FlashBuilder
|
|
567
|
+
icon: (icon: string | false) => FlashBuilder
|
|
568
|
+
info: () => FlashBuilder
|
|
569
|
+
level: (level: FlashLevel) => FlashBuilder
|
|
570
|
+
noAutoDismiss: () => FlashBuilder
|
|
571
|
+
onClose: (method: string, args?: unknown[]) => FlashBuilder
|
|
572
|
+
position: (position: FlashPosition) => FlashBuilder
|
|
573
|
+
progressBar: (value?: boolean) => FlashBuilder
|
|
574
|
+
success: () => FlashBuilder
|
|
575
|
+
title: (title: string) => FlashBuilder
|
|
576
|
+
warning: () => FlashBuilder
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
interface FlashCallback = {
|
|
580
|
+
args?: unknown[]
|
|
581
|
+
method: string
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
interface FlashFrame = {
|
|
585
|
+
actions?: FlashAction[]
|
|
586
|
+
dismissible?: boolean
|
|
587
|
+
duration?: number
|
|
588
|
+
icon?: string | false
|
|
589
|
+
level: 'success' | 'error' | 'warning' | 'info'
|
|
590
|
+
message: string
|
|
591
|
+
onClose?: FlashCallback
|
|
592
|
+
position?: FlashPosition
|
|
593
|
+
progressBar?: boolean
|
|
594
|
+
title?: string
|
|
595
|
+
type: 'flash'
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
interface FlashMessage = {
|
|
599
|
+
actions?: FlashAction[]
|
|
600
|
+
dismissible?: boolean
|
|
601
|
+
duration?: number
|
|
602
|
+
icon?: string | false
|
|
603
|
+
level: 'success' | 'error' | 'warning' | 'info'
|
|
604
|
+
message: string
|
|
605
|
+
onClose?: FlashCallback
|
|
606
|
+
position?: FlashPosition
|
|
607
|
+
progressBar?: boolean
|
|
608
|
+
title?: string
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
interface FlashOptions = {
|
|
612
|
+
actions?: FlashAction[]
|
|
613
|
+
dismissible?: boolean
|
|
614
|
+
duration?: number
|
|
615
|
+
icon?: string | false
|
|
616
|
+
level?: 'success' | 'error' | 'warning' | 'info'
|
|
617
|
+
onClose?: FlashCallback
|
|
618
|
+
position?: FlashPosition
|
|
619
|
+
progressBar?: boolean
|
|
620
|
+
title?: string
|
|
621
|
+
type?: 'success' | 'error' | 'warning' | 'info'
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
interface FlashProps = {
|
|
625
|
+
[key: string]: unknown
|
|
626
|
+
duration?: number
|
|
627
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
interface FlowChain = {
|
|
631
|
+
confirm: (message: string) => FlowChain<T>
|
|
632
|
+
debounce: (ms: string | number) => FlowChain<T>
|
|
633
|
+
readonly __isFlow: true
|
|
634
|
+
readonly __key: string | undefined
|
|
635
|
+
readonly __modifiers: string[]
|
|
636
|
+
readonly __target: T
|
|
637
|
+
readonly blur: FlowChain<T>
|
|
638
|
+
readonly camel: FlowChain<T>
|
|
639
|
+
readonly capture: FlowChain<T>
|
|
640
|
+
readonly document: FlowChain<T>
|
|
641
|
+
readonly fill: FlowChain<T>
|
|
642
|
+
readonly lazy: FlowChain<T>
|
|
643
|
+
readonly live: FlowChain<T>
|
|
644
|
+
readonly once: FlowChain<T>
|
|
645
|
+
readonly outside: FlowChain<T>
|
|
646
|
+
readonly passive: FlowChain<T>
|
|
647
|
+
readonly prevent: FlowChain<T>
|
|
648
|
+
readonly self: FlowChain<T>
|
|
649
|
+
readonly stop: FlowChain<T>
|
|
650
|
+
readonly window: FlowChain<T>
|
|
651
|
+
throttle: (ms: string | number) => FlowChain<T>
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
interface FlowConfigShape = {
|
|
655
|
+
cspSafe: boolean
|
|
656
|
+
persistentMiddleware: (string | MiddlewareClass)[]
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
interface FlowConnection = {
|
|
660
|
+
actions: number
|
|
661
|
+
connectedAt: number
|
|
662
|
+
id: string
|
|
663
|
+
ip: string
|
|
664
|
+
lastActivityAt: number
|
|
665
|
+
user: string | null
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
interface FlowEffects = {
|
|
669
|
+
downloads: { filename: string; content: string; mime: string;}[]
|
|
670
|
+
errors: Record<string, string[]>
|
|
671
|
+
events: { name: string; data: Record<string, unknown>; to?: string; self?: boolean;}[]
|
|
672
|
+
flashes: FlashMessage[]
|
|
673
|
+
redirectUrl: string | null
|
|
674
|
+
scripts: string[]
|
|
675
|
+
shouldRefresh: boolean
|
|
676
|
+
title: string | null
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
interface FlowEvents = {}
|
|
680
|
+
|
|
681
|
+
interface FlowStore = {}
|
|
682
|
+
|
|
683
|
+
interface ForProps = {
|
|
684
|
+
children: (item: T, index: number) => HtmlNode
|
|
685
|
+
each: readonly T[]
|
|
686
|
+
keyBy?: string
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
interface InfiniteScrollProps = {
|
|
690
|
+
[key: string]: unknown
|
|
691
|
+
children?: unknown
|
|
692
|
+
class?: string
|
|
693
|
+
onMore: unknown
|
|
694
|
+
show?: boolean
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
interface LabelProps = {
|
|
698
|
+
[key: string]: unknown
|
|
699
|
+
children?: unknown
|
|
700
|
+
class?: string
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
interface LegendProps = {
|
|
704
|
+
[key: string]: unknown
|
|
705
|
+
children?: unknown
|
|
706
|
+
class?: string
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
interface LinkProps = {
|
|
710
|
+
[key: string]: unknown
|
|
711
|
+
current?: boolean
|
|
712
|
+
exact?: boolean
|
|
713
|
+
hover?: boolean
|
|
714
|
+
href: string
|
|
715
|
+
preserveScroll?: boolean
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
interface ListboxOption = {
|
|
719
|
+
label: unknown
|
|
720
|
+
value: string | number
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
interface ListboxProps = {
|
|
724
|
+
[key: string]: unknown
|
|
725
|
+
bind: unknown
|
|
726
|
+
buttonClass?: string
|
|
727
|
+
class?: string
|
|
728
|
+
multiple?: boolean
|
|
729
|
+
optionClass?: string
|
|
730
|
+
options: ListboxOption[]
|
|
731
|
+
optionsClass?: string
|
|
732
|
+
placeholder?: string
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
interface LoadingProps = {
|
|
736
|
+
[key: string]: unknown
|
|
737
|
+
children?: unknown
|
|
738
|
+
class?: string
|
|
739
|
+
delay?: boolean
|
|
740
|
+
hide?: boolean
|
|
741
|
+
skeleton?: boolean | SkeletonProps
|
|
742
|
+
tag?: string
|
|
743
|
+
target?: string | string[]
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
interface ModalProps = {
|
|
747
|
+
[key: string]: unknown
|
|
748
|
+
children?: unknown
|
|
749
|
+
class?: string
|
|
750
|
+
closable?: boolean
|
|
751
|
+
name?: string
|
|
752
|
+
onClose?: unknown
|
|
753
|
+
show?: unknown
|
|
754
|
+
title?: unknown
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
interface PageClassWithMeta = {
|
|
758
|
+
new (): Component
|
|
759
|
+
head?: string
|
|
760
|
+
layout?: new () => Layout
|
|
761
|
+
models?: Record<string, typeof BaseModel>
|
|
762
|
+
name: string
|
|
763
|
+
title?: string
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
interface PagerProps = {
|
|
767
|
+
[key: string]: unknown
|
|
768
|
+
activeClass?: string
|
|
769
|
+
class?: string
|
|
770
|
+
hover?: boolean
|
|
771
|
+
linkClass?: string
|
|
772
|
+
nextLabel?: string
|
|
773
|
+
paginator: PagerLike
|
|
774
|
+
params?: Record<string, string | number | null | undefined>
|
|
775
|
+
prevLabel?: string
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
interface Paginator = {
|
|
779
|
+
data: T[]
|
|
780
|
+
elements: (each?: number) => (number | '...')[]
|
|
781
|
+
from: number
|
|
782
|
+
hasMorePages: boolean
|
|
783
|
+
lastPage: number
|
|
784
|
+
onFirstPage: boolean
|
|
785
|
+
page: number
|
|
786
|
+
perPage: number
|
|
787
|
+
to: number
|
|
788
|
+
total: number
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
interface PatchFrame = {
|
|
792
|
+
actionError?: boolean
|
|
793
|
+
checksum?: string
|
|
794
|
+
component: string
|
|
795
|
+
dataDelta?: SnapshotData
|
|
796
|
+
dataRemoved?: string[]
|
|
797
|
+
errors?: Record<string, string[]>
|
|
798
|
+
html?: string
|
|
799
|
+
memo?: SnapshotMemo
|
|
800
|
+
partial?: boolean
|
|
801
|
+
scripts?: string[]
|
|
802
|
+
snapshot?: Snapshot
|
|
803
|
+
title?: string
|
|
804
|
+
type: 'patch'
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
interface PopoverProps = {
|
|
808
|
+
[key: string]: unknown
|
|
809
|
+
buttonClass?: string
|
|
810
|
+
children?: unknown
|
|
811
|
+
class?: string
|
|
812
|
+
label?: unknown
|
|
813
|
+
panelClass?: string
|
|
814
|
+
trigger?: unknown
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
interface PresenceMember = {
|
|
818
|
+
[key: string]: unknown
|
|
819
|
+
id: string | number
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
interface RadioGroupProps = {
|
|
823
|
+
[key: string]: unknown
|
|
824
|
+
bind: unknown
|
|
825
|
+
class?: string
|
|
826
|
+
optionClass?: string
|
|
827
|
+
options: RadioOption[]
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
interface RadioOption = {
|
|
831
|
+
label: unknown
|
|
832
|
+
value: string | number
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
interface RedirectFlash = {
|
|
836
|
+
with: (message: string, level: FlashLevel) => RedirectFlash
|
|
837
|
+
withError: (message: string) => RedirectFlash
|
|
838
|
+
withInfo: (message: string) => RedirectFlash
|
|
839
|
+
withSuccess: (message: string) => RedirectFlash
|
|
840
|
+
withWarning: (message: string) => RedirectFlash
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
interface RedirectFrame = {
|
|
844
|
+
sessionToken?: string
|
|
845
|
+
type: 'redirect'
|
|
846
|
+
url: string
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
interface SectionContentProps = {
|
|
850
|
+
children?: unknown
|
|
851
|
+
name: string
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
interface SectionOutletProps = {
|
|
855
|
+
children?: unknown
|
|
856
|
+
name: string
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
interface SelectOption = {
|
|
860
|
+
label: unknown
|
|
861
|
+
value: string | number
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
interface SelectProps = {
|
|
865
|
+
[key: string]: unknown
|
|
866
|
+
bind: unknown
|
|
867
|
+
class?: string
|
|
868
|
+
options: SelectOption[]
|
|
869
|
+
placeholder?: string
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
interface SessionOptions = {
|
|
873
|
+
key?: string
|
|
874
|
+
scoped?: boolean
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
interface SharedStore = {
|
|
878
|
+
get: (key: string) => unknown | undefined
|
|
879
|
+
has: (key: string) => boolean
|
|
880
|
+
set: (key: string, value: unknown) => void
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
interface SkeletonProps = {
|
|
884
|
+
[key: string]: unknown
|
|
885
|
+
class?: string
|
|
886
|
+
height?: string
|
|
887
|
+
lines?: number
|
|
888
|
+
rounded?: string | boolean
|
|
889
|
+
width?: string
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
interface SliderProps = {
|
|
893
|
+
[key: string]: unknown
|
|
894
|
+
bind?: unknown
|
|
895
|
+
children?: unknown
|
|
896
|
+
class?: string
|
|
897
|
+
inputClass?: string
|
|
898
|
+
inputStyle?: string
|
|
899
|
+
inputStyleExpression?: string
|
|
900
|
+
max?: number
|
|
901
|
+
min?: number
|
|
902
|
+
name?: string
|
|
903
|
+
step?: number
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
interface Snapshot = {
|
|
907
|
+
checksum: string
|
|
908
|
+
data: SnapshotData
|
|
909
|
+
memo: SnapshotMemo
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
interface SnapshotMemo = {
|
|
913
|
+
children: string[]
|
|
914
|
+
iat?: number | undefined
|
|
915
|
+
id: string
|
|
916
|
+
listeners?: Record<string, string> | undefined
|
|
917
|
+
name: string
|
|
918
|
+
path: string
|
|
919
|
+
presence?: { prop: string; channel: string;}[] | undefined
|
|
920
|
+
shared?: { prop: string; channel: string;}[] | undefined
|
|
921
|
+
slots?: Record<string, string> | undefined
|
|
922
|
+
sub?: string | undefined
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
interface SwitchProps = {
|
|
926
|
+
[key: string]: unknown
|
|
927
|
+
bind: unknown
|
|
928
|
+
children?: unknown
|
|
929
|
+
class?: string
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
interface Synth = {
|
|
933
|
+
dehydrate: (value: T, meta: Record<string, unknown>) => unknown
|
|
934
|
+
hydrate: (data: unknown, meta: Record<string, unknown>) => T | Promise<T>
|
|
935
|
+
key: string
|
|
936
|
+
match: (value: unknown) => value is T
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
interface TabItem = {
|
|
940
|
+
content: unknown
|
|
941
|
+
label: unknown
|
|
942
|
+
name?: string
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
interface TableColumn = {
|
|
946
|
+
class?: string
|
|
947
|
+
key: string
|
|
948
|
+
label: unknown
|
|
949
|
+
render?: (row: T) => unknown
|
|
950
|
+
sortable?: boolean
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
interface TableProps = {
|
|
954
|
+
[key: string]: unknown
|
|
955
|
+
class?: string
|
|
956
|
+
columns: TableColumn<T>[]
|
|
957
|
+
hover?: boolean
|
|
958
|
+
params?: Record<string, string | number | null | undefined>
|
|
959
|
+
rowKey?: string
|
|
960
|
+
rows: T[]
|
|
961
|
+
sortBy?: string
|
|
962
|
+
sortDir?: 'asc' | 'desc'
|
|
963
|
+
theadClass?: string
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
interface TabsProps = {
|
|
967
|
+
[key: string]: unknown
|
|
968
|
+
class?: string
|
|
969
|
+
items: TabItem[]
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
interface ToggleGroupProps = {
|
|
973
|
+
[key: string]: unknown
|
|
974
|
+
bind?: unknown
|
|
975
|
+
class?: string
|
|
976
|
+
multiple?: boolean
|
|
977
|
+
name?: string
|
|
978
|
+
optionClass?: string
|
|
979
|
+
options: ToggleOption[]
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
interface ToggleOption = {
|
|
983
|
+
disabled?: boolean
|
|
984
|
+
label?: unknown
|
|
985
|
+
value: string
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
interface TooltipProps = {
|
|
989
|
+
[key: string]: unknown
|
|
990
|
+
children?: unknown
|
|
991
|
+
class?: string
|
|
992
|
+
content?: unknown
|
|
993
|
+
placement?: 'top' | 'bottom'
|
|
994
|
+
text?: unknown
|
|
995
|
+
tooltipClass?: string
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
interface UploadRef = {
|
|
999
|
+
__flow_upload: true
|
|
1000
|
+
mime: string
|
|
1001
|
+
originalName: string
|
|
1002
|
+
sig: string
|
|
1003
|
+
size: number
|
|
1004
|
+
tempDisk?: string | undefined
|
|
1005
|
+
tmpPath: string
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
interface UrlOptions = {
|
|
1009
|
+
as?: string
|
|
1010
|
+
history?: 'replace' | 'push'
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
interface VirtualizeProps = {
|
|
1014
|
+
children: (item: T, index: number) => HtmlNode
|
|
1015
|
+
class?: string
|
|
1016
|
+
height?: number
|
|
1017
|
+
itemHeight: number
|
|
1018
|
+
items: readonly T[]
|
|
1019
|
+
onWindow?: unknown
|
|
1020
|
+
overscan?: number
|
|
1021
|
+
start?: number
|
|
1022
|
+
total?: number
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
type Constructor = abstract new (...args: any[]) => T
|
|
1026
|
+
|
|
1027
|
+
type DurableOption = boolean | { ttl?: string; scope?: 'user' | 'session';}
|
|
1028
|
+
|
|
1029
|
+
type EventName = never
|
|
1030
|
+
|
|
1031
|
+
type EventPayload = FlowEvents[K]
|
|
1032
|
+
|
|
1033
|
+
type FlashActionVariant = 'solid' | 'soft' | 'ghost'
|
|
1034
|
+
|
|
1035
|
+
type FlashLevel = 'success' | 'error' | 'warning' | 'info'
|
|
1036
|
+
|
|
1037
|
+
type FlashPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'
|
|
1038
|
+
|
|
1039
|
+
type HtmlNode = { html: string;}
|
|
1040
|
+
|
|
1041
|
+
type Mixin = (Base: TIn) => TOut
|
|
1042
|
+
|
|
1043
|
+
type PresenceChannel = string | ((self: Record<string, any>) => string)
|
|
1044
|
+
|
|
1045
|
+
type SharedChannel = string | ((self: Record<string, any>) => string)
|
|
1046
|
+
|
|
1047
|
+
type SnapshotData = { [x: string]: SnapshotTuple;}
|
|
1048
|
+
|
|
1049
|
+
type ValidationRules = { [x: string]: (rule: RuleBuilder) => FieldRule;}
|
|
1050
|
+
|
|
1051
|
+
## ./browser `(./src/browser/index.ts)`
|
|
1052
|
+
|
|
1053
|
+
class FlowBrowser = {
|
|
1054
|
+
new (_browser: LaunchedBrowser, _session: CdpSession): FlowBrowser
|
|
1055
|
+
static available: () => boolean
|
|
1056
|
+
static open: (url: string, options?: OpenOptions) => Promise<FlowBrowser>
|
|
1057
|
+
attr: (selector: string, name: string) => Promise<string | null>
|
|
1058
|
+
click: (selector: string) => Promise<void>
|
|
1059
|
+
close: () => Promise<void>
|
|
1060
|
+
consoleErrors: () => string[]
|
|
1061
|
+
evaluate: <T = unknown>(expression: string) => Promise<T>
|
|
1062
|
+
fill: (selector: string, value: string) => Promise<void>
|
|
1063
|
+
goto: (url: string, options?: OpenOptions) => Promise<void>
|
|
1064
|
+
html: () => Promise<string>
|
|
1065
|
+
pageErrors: () => string[]
|
|
1066
|
+
text: (selector: string) => Promise<string>
|
|
1067
|
+
value: (selector: string) => Promise<string>
|
|
1068
|
+
waitForSelector: (selector: string, timeoutMs?: number) => Promise<void>
|
|
1069
|
+
waitForText: (selector: string, text: string, timeoutMs?: number) => Promise<void>
|
|
1070
|
+
waitUntil: (expression: string, label: string, timeoutMs?: number) => Promise<void>
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
function findChrome = () => string | null
|
|
1074
|
+
|
|
1075
|
+
interface OpenOptions = {
|
|
1076
|
+
timeout?: number
|
|
1077
|
+
waitForConnection?: boolean
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
## ./compiler-helpers `(./src/compiler/helpers.ts)`
|
|
1081
|
+
|
|
1082
|
+
function __esc = (v: unknown) => string
|
|
1083
|
+
|
|
1084
|
+
function __escAttr = (v: unknown) => string
|
|
1085
|
+
|
|
1086
|
+
## ./store `(./src/store.ts)`
|
|
1087
|
+
|
|
1088
|
+
function clientStore = () => Record<string, unknown>
|
|
1089
|
+
|
|
1090
|
+
function defineStore = (initial: Record<string, unknown>) => void
|
|
1091
|
+
|
|
1092
|
+
function initClientStore = (alpine: AlpineStores) => Record<string, unknown>
|
|
1093
|
+
|
|
1094
|
+
interface FlowStore = {}
|
|
1095
|
+
|
|
1096
|
+
## ./testing `(./src/testing.ts)`
|
|
1097
|
+
|
|
1098
|
+
class FlowTest = {
|
|
1099
|
+
new <T extends Component>(page: T, name: string): FlowTest<T>
|
|
1100
|
+
static mount: <T extends Component>(PageClass: PageClass<T>, props?: Partial<T>) => Promise<FlowTest<T>>
|
|
1101
|
+
assertDispatched: (eventName: string) => FlowTest<T>
|
|
1102
|
+
assertDontSee: (text: string) => FlowTest<T>
|
|
1103
|
+
assertErrored: (match?: string | RegExp) => FlowTest<T>
|
|
1104
|
+
assertFlashed: (level?: string, message?: string) => FlowTest<T>
|
|
1105
|
+
assertHasErrors: (field: string, message?: string) => FlowTest<T>
|
|
1106
|
+
assertNoErrors: () => FlowTest<T>
|
|
1107
|
+
assertNotRedirected: () => FlowTest<T>
|
|
1108
|
+
assertRedirectedTo: (url: string) => FlowTest<T>
|
|
1109
|
+
assertSee: (text: string) => FlowTest<T>
|
|
1110
|
+
call: (method: string, ...args: unknown[]) => Promise<FlowTest<T>>
|
|
1111
|
+
effects: () => FlowEffects | null
|
|
1112
|
+
errors: () => Record<string, string[]>
|
|
1113
|
+
flashes: () => FlowEffects['flashes']
|
|
1114
|
+
html: () => string
|
|
1115
|
+
lastError: () => Error | null
|
|
1116
|
+
page: () => T
|
|
1117
|
+
render: () => Promise<FlowTest<T>>
|
|
1118
|
+
seed: (prop: keyof T, value: unknown) => Promise<FlowTest<T>>
|
|
1119
|
+
set: (prop: keyof T, value: unknown) => Promise<FlowTest<T>>
|
|
1120
|
+
snapshot: () => Snapshot | null
|
|
1121
|
+
tolerateErrors: () => FlowTest<T>
|
|
1122
|
+
update: (prop: keyof T, value: unknown) => Promise<FlowTest<T>>
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
function hydrate = <T extends Component>(snapshot: Snapshot, PageClass: new () => T) => Promise<T>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/flow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "stable",
|
|
6
6
|
"private": false,
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"CHANGELOG.md",
|
|
21
|
+
"api-surface.md",
|
|
21
22
|
"src",
|
|
22
23
|
"!src/**/*.test.ts",
|
|
23
24
|
"!src/**/*.test.tsx",
|
|
@@ -46,14 +47,14 @@
|
|
|
46
47
|
"@alpinejs/morph": "^3.14.9",
|
|
47
48
|
"@alpinejs/persist": "^3.14.9",
|
|
48
49
|
"@alpinejs/resize": "^3.14.9",
|
|
49
|
-
"@zerotal/core": "1.
|
|
50
|
-
"@zerotal/orm": "1.
|
|
51
|
-
"@zerotal/validator": "1.
|
|
50
|
+
"@zerotal/core": "1.7.0",
|
|
51
|
+
"@zerotal/orm": "1.7.0",
|
|
52
|
+
"@zerotal/validator": "1.7.0",
|
|
52
53
|
"alpinejs": "^3.14.9",
|
|
53
54
|
"typescript": "^5.8.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@zerotal/broadcasting": "1.
|
|
57
|
+
"@zerotal/broadcasting": "1.7.0",
|
|
57
58
|
"@types/alpinejs": "^3.13.10",
|
|
58
59
|
"@types/alpinejs__anchor": "^3.13.1",
|
|
59
60
|
"@types/alpinejs__collapse": "^3.13.4",
|
package/src/Component.ts
CHANGED
|
@@ -493,8 +493,19 @@ export abstract class Component {
|
|
|
493
493
|
|
|
494
494
|
// ── @internal: framework bookkeeping, not part of the developer API ──────────
|
|
495
495
|
|
|
496
|
-
|
|
497
|
-
|
|
496
|
+
// `_skipMount` used to live here, declared as "set to true by hydrate() so the
|
|
497
|
+
// framework skips calling onMount()". Nothing ever read it. Mount-skipping is
|
|
498
|
+
// structural and always has been: the router branches between `onHydrate()`
|
|
499
|
+
// and `onMount()`, and the action dispatcher calls `onMount()` only when an
|
|
500
|
+
// action asks for it.
|
|
501
|
+
//
|
|
502
|
+
// It was removed rather than wired up because wiring it would have been wrong.
|
|
503
|
+
// `$refresh` and `$mount` deliberately re-run `onMount()` on a page that was
|
|
504
|
+
// hydrated — so a flag whose stated meaning is "this page has been hydrated,
|
|
505
|
+
// do not mount it" would have broken both the moment anyone honoured it. An
|
|
506
|
+
// inert flag that reads as load-bearing is worse than none: the next person
|
|
507
|
+
// building render modes would reach for it, find it does nothing, and ship a
|
|
508
|
+
// double-mount. `hooks.test.ts` pins the real guarantee instead.
|
|
498
509
|
|
|
499
510
|
/** Populated by flash() — read by the WS handler to emit flash frames. @internal */
|
|
500
511
|
_flashes: FlashMessage[] = [];
|
package/src/client/bridge.ts
CHANGED
|
@@ -2684,7 +2684,21 @@ async function _navigateTo(href: string, options: NavigateOptions = {}): Promise
|
|
|
2684
2684
|
// browser supports it, for a smooth cross-page animation; falls back to an
|
|
2685
2685
|
// instant swap otherwise.
|
|
2686
2686
|
const _swap = (): void => {
|
|
2687
|
-
|
|
2687
|
+
// Page-level state scripts only: the server renders one as a direct child of
|
|
2688
|
+
// <body>, after the body content, while every child island's script sits
|
|
2689
|
+
// *inside* that content.
|
|
2690
|
+
//
|
|
2691
|
+
// This used to be `document.querySelector('[id^="flow-state-"]')`, which
|
|
2692
|
+
// matches in document order — so on any page with an island it removed the
|
|
2693
|
+
// first island's script and left the page's own behind. The outgoing
|
|
2694
|
+
// snapshot was orphaned, and ids are random per request, so they accumulated
|
|
2695
|
+
// one per navigation for as long as the tab stayed open.
|
|
2696
|
+
//
|
|
2697
|
+
// Removing *all* of them rather than just this page's also clears whatever a
|
|
2698
|
+
// previously-buggy session left behind.
|
|
2699
|
+
for (const stale of document.querySelectorAll('body > script[id^="flow-state-"]')) {
|
|
2700
|
+
stale.remove();
|
|
2701
|
+
}
|
|
2688
2702
|
document.body.appendChild(incomingState.cloneNode(true));
|
|
2689
2703
|
currentRoot.replaceWith(incomingClone);
|
|
2690
2704
|
_cleanupDisconnected();
|
package/src/dehydrate.ts
CHANGED
|
@@ -206,9 +206,9 @@ export async function hydrate<T extends Component>(
|
|
|
206
206
|
// still someone else's state.
|
|
207
207
|
assertSnapshotSubject(snapshot);
|
|
208
208
|
|
|
209
|
-
// 3. Fresh blank instance
|
|
209
|
+
// 3. Fresh blank instance. `onMount()` is not called here and the dispatcher
|
|
210
|
+
// does not call it either — the skip is structural, not a flag on the page.
|
|
210
211
|
const page = new PageClass();
|
|
211
|
-
(page as Record<string, unknown>)["_skipMount"] = true;
|
|
212
212
|
|
|
213
213
|
// 4. Restore slots + each property (see applySnapshotData).
|
|
214
214
|
await applySnapshotData(page, snapshot);
|
package/src/durable.ts
CHANGED
|
@@ -237,7 +237,8 @@ export async function restoreDurable(page: Component, ctx: HttpContext): Promise
|
|
|
237
237
|
if (!key) return false;
|
|
238
238
|
const stored = await _store.get(key);
|
|
239
239
|
if (!stored || !verifySnapshot(stored)) return false;
|
|
240
|
-
|
|
240
|
+
// Returning `true` is what skips the mount: the caller branches on it and runs
|
|
241
|
+
// `onHydrate()` instead. Nothing is marked on the page.
|
|
241
242
|
await applySnapshotData(page, stored);
|
|
242
243
|
return true;
|
|
243
244
|
}
|