@bitstillery/mithril 3.8.0 → 3.9.1
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/api/router.ts +13 -1
- package/index.ts +24 -4
- package/package.json +5 -5
- package/render/vnode.ts +16 -9
- package/ssrContext.ts +3 -1
- package/state.ts +52 -33
- package/store.ts +15 -15
package/api/router.ts
CHANGED
|
@@ -26,6 +26,15 @@ export interface RouteResolver<Attrs = Record<string, any>, State = any> {
|
|
|
26
26
|
export type SSRState = Record<string, any>
|
|
27
27
|
export type SSRResult = string | {html: string; state: SSRState}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* A route parameter as the URL can carry it. Path params are always strings; the querystring parser
|
|
31
|
+
* also turns `true`/`false` into booleans and `a[]=`/`a[b]=` keys into arrays and objects. A plain
|
|
32
|
+
* object in `history.state` is merged over the params too, so values put there must keep to this
|
|
33
|
+
* shape for the type to hold.
|
|
34
|
+
*/
|
|
35
|
+
export type RouteParamValue = string | boolean | RouteParamValue[] | {[key: string]: RouteParamValue}
|
|
36
|
+
export type RouteParams = Record<string, RouteParamValue>
|
|
37
|
+
|
|
29
38
|
export interface Route {
|
|
30
39
|
(path: string, params?: Record<string, any>, shouldReplaceHistory?: boolean): void
|
|
31
40
|
(path: string, component: ComponentType, shouldReplaceHistory?: boolean): void
|
|
@@ -33,7 +42,10 @@ export interface Route {
|
|
|
33
42
|
get: () => string
|
|
34
43
|
prefix: string
|
|
35
44
|
link: (vnode: VnodeType) => string
|
|
36
|
-
param:
|
|
45
|
+
param: {
|
|
46
|
+
(key: string): RouteParamValue | undefined
|
|
47
|
+
(): RouteParams
|
|
48
|
+
}
|
|
37
49
|
params: Record<string, any>
|
|
38
50
|
Link: ComponentType
|
|
39
51
|
SKIP: {}
|
package/index.ts
CHANGED
|
@@ -12,7 +12,15 @@ import censor from './util/censor'
|
|
|
12
12
|
import nextTick from './util/next_tick'
|
|
13
13
|
import domFor from './render/domFor'
|
|
14
14
|
import {signal, computed, effect, Signal, ComputedSignal, setSignalRedrawCallback, getSignalComponents} from './signal'
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
state,
|
|
17
|
+
watch,
|
|
18
|
+
registerState,
|
|
19
|
+
getRegisteredStates,
|
|
20
|
+
clearStateRegistry,
|
|
21
|
+
copyGlobalStatesToContext,
|
|
22
|
+
allowComputed,
|
|
23
|
+
} from './state'
|
|
16
24
|
|
|
17
25
|
import type {Vnode, Children, ComponentType} from './render/vnode'
|
|
18
26
|
import type {Hyperscript} from './render/hyperscript'
|
|
@@ -101,8 +109,20 @@ setSignalRedrawCallback((sig: Signal<any>) => {
|
|
|
101
109
|
})
|
|
102
110
|
|
|
103
111
|
// Export signals API
|
|
104
|
-
export {
|
|
105
|
-
|
|
112
|
+
export {
|
|
113
|
+
signal,
|
|
114
|
+
computed,
|
|
115
|
+
effect,
|
|
116
|
+
Signal,
|
|
117
|
+
ComputedSignal,
|
|
118
|
+
state,
|
|
119
|
+
watch,
|
|
120
|
+
registerState,
|
|
121
|
+
getRegisteredStates,
|
|
122
|
+
clearStateRegistry,
|
|
123
|
+
allowComputed,
|
|
124
|
+
}
|
|
125
|
+
export type {DeepPartial, State, StateArray, StateOptions, StateSignals, Unwatch} from './state'
|
|
106
126
|
|
|
107
127
|
// Export Store class
|
|
108
128
|
export {Store} from './store'
|
|
@@ -140,7 +160,7 @@ export type {
|
|
|
140
160
|
} from './render/vnode'
|
|
141
161
|
export {MithrilComponent}
|
|
142
162
|
export type {Hyperscript} from './render/hyperscript'
|
|
143
|
-
export type {Route, RouteResolver, RedirectObject} from './api/router'
|
|
163
|
+
export type {Route, RouteParams, RouteParamValue, RouteResolver, RedirectObject} from './api/router'
|
|
144
164
|
export type {Render, Redraw, Mount} from './api/mount-redraw'
|
|
145
165
|
|
|
146
166
|
// Namespace merge: enables m.Vnode<Attrs> and m.Children when using import m from '@bitstillery/mithril'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitstillery/mithril",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.1",
|
|
4
4
|
"description": "Mithril + Signals, Store and SSR",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bitstillery",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"lint:ts": "bun run lint:ts-format && bun run lint:ts-syntax && bun run lint:ts-types",
|
|
53
53
|
"lint:ts-format": "oxfmt",
|
|
54
54
|
"lint:ts-syntax": "oxlint -c .oxlintrc.json",
|
|
55
|
-
"lint:ts-types": "
|
|
55
|
+
"lint:ts-types": "tsc --noEmit",
|
|
56
56
|
"test": "bun test",
|
|
57
57
|
"bench": "NODE_ENV=production bun run bench/index.ts",
|
|
58
58
|
"bench:hyperscript": "NODE_ENV=production bun run bench/index.ts hyperscript",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"bench:signal": "NODE_ENV=production bun run bench/index.ts signal",
|
|
61
61
|
"bench:state": "NODE_ENV=production bun run bench/index.ts state",
|
|
62
62
|
"bench:profile": "bun --cpu-prof-md run bench/index.ts",
|
|
63
|
-
"prepublishOnly": "bun run lint:ts",
|
|
63
|
+
"prepublishOnly": "oxfmt --check && bun run lint:ts-syntax && bun run lint:ts-types",
|
|
64
64
|
"pack:dry-run": "npm pack --dry-run",
|
|
65
65
|
"release": "./scripts/release.sh",
|
|
66
66
|
"release:patch": "./scripts/release.sh --release-as patch",
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
79
79
|
"@codemirror/view": "^6.39.1",
|
|
80
80
|
"@types/bun": "^1.3.9",
|
|
81
|
-
"@typescript/native-preview": "^7.0.0-dev.20260120.1",
|
|
82
81
|
"codemirror": "^6.0.1",
|
|
83
82
|
"marked": "^15.0.4",
|
|
84
83
|
"marked-gfm-heading-id": "^4.0.0",
|
|
@@ -86,6 +85,7 @@
|
|
|
86
85
|
"oxfmt": "^0.32.0",
|
|
87
86
|
"oxlint": "^1.30.0",
|
|
88
87
|
"standard-version": "^9.5.0",
|
|
89
|
-
"tippy.js": "^6.3.7"
|
|
88
|
+
"tippy.js": "^6.3.7",
|
|
89
|
+
"typescript": "^7.0.2"
|
|
90
90
|
}
|
|
91
91
|
}
|
package/render/vnode.ts
CHANGED
|
@@ -28,19 +28,26 @@ export type VnodeDOM<Attrs = Record<string, any>, State = any> = ComponentVnode<
|
|
|
28
28
|
*/
|
|
29
29
|
export type ComponentVnode<Attrs = Record<string, any>, State = any> = Omit<Vnode<Attrs, State>, 'attrs'> & {attrs: Attrs}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* The hooks are declared as methods, not function-typed properties: under `strictFunctionTypes` a
|
|
33
|
+
* property's parameters are checked contravariantly, so `Component<{name: string}>` would not be a
|
|
34
|
+
* `Component<Record<string, any>>` and `m(Icon, attrs)` could not be passed where `Children` is expected.
|
|
35
|
+
* Method parameters are bivariant, which matches how Mithril really calls them — with the vnode it
|
|
36
|
+
* built for that component.
|
|
37
|
+
*/
|
|
31
38
|
export interface Component<Attrs = Record<string, any>, State = any> {
|
|
32
|
-
oninit
|
|
33
|
-
oncreate
|
|
34
|
-
onbeforeupdate
|
|
35
|
-
onupdate
|
|
36
|
-
onbeforeremove
|
|
37
|
-
onremove
|
|
38
|
-
view
|
|
39
|
+
oninit?(vnode: ComponentVnode<Attrs, State>): void
|
|
40
|
+
oncreate?(vnode: ComponentVnode<Attrs, State>): void
|
|
41
|
+
onbeforeupdate?(vnode: ComponentVnode<Attrs, State>, old: ComponentVnode<Attrs, State>): boolean | void
|
|
42
|
+
onupdate?(vnode: ComponentVnode<Attrs, State>): void
|
|
43
|
+
onbeforeremove?(vnode: ComponentVnode<Attrs, State>): Promise<any> | void
|
|
44
|
+
onremove?(vnode: ComponentVnode<Attrs, State>): void
|
|
45
|
+
view(vnode: ComponentVnode<Attrs, State>): Children | Vnode | null
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
export interface ComponentFactory<Attrs = Record<string, any>, State = any> {
|
|
42
49
|
(...args: any[]): Component<Attrs, State>
|
|
43
|
-
view
|
|
50
|
+
view?(vnode: ComponentVnode<Attrs, State>): Children | Vnode | null
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export type ComponentType<Attrs = Record<string, any>, State = any> =
|
|
@@ -55,7 +62,7 @@ export type ComponentType<Attrs = Record<string, any>, State = any> =
|
|
|
55
62
|
*/
|
|
56
63
|
export abstract class MithrilComponent<Attrs = Record<string, any>> {
|
|
57
64
|
/** Required for JSX attribute type-checking - do not use directly */
|
|
58
|
-
private readonly __tsx_attrs!: (unknown extends Attrs ? Record<string, any> : Attrs) & {key?: string | number}
|
|
65
|
+
private readonly __tsx_attrs!: (unknown extends Attrs ? Record<string, any> : Attrs) & {key?: string | number | null}
|
|
59
66
|
|
|
60
67
|
oninit?(vnode: ComponentVnode<Attrs>): void
|
|
61
68
|
oncreate?(vnode: ComponentVnode<Attrs>): void
|
package/ssrContext.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* request's context. No globals, safe under concurrent requests.
|
|
6
6
|
* In the browser, getSSRContext() returns undefined and runWithContext just runs fn.
|
|
7
7
|
*/
|
|
8
|
+
import type {Store} from './store'
|
|
9
|
+
|
|
8
10
|
type StorageLike = {
|
|
9
11
|
getStore(): SSRAccessContext | undefined
|
|
10
12
|
run<T>(context: SSRAccessContext, fn: () => T): T
|
|
@@ -28,7 +30,7 @@ try {
|
|
|
28
30
|
* that runs inside the same runWithContext() call.
|
|
29
31
|
*/
|
|
30
32
|
export interface SSRAccessContext {
|
|
31
|
-
store?:
|
|
33
|
+
store?: Store
|
|
32
34
|
/** Per-request state registry for serialization; fresh Map per request. */
|
|
33
35
|
stateRegistry: Map<string, {state: any; initial: any}>
|
|
34
36
|
sessionId?: string
|
package/state.ts
CHANGED
|
@@ -232,15 +232,17 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
232
232
|
|
|
233
233
|
// Handle arrays
|
|
234
234
|
if (Array.isArray(obj)) {
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
|
|
235
|
+
// Init, push/unshift, splice and index assignment all wrap through here, so an element typed as
|
|
236
|
+
// `State<E>` is one: objects and arrays become their own state proxy (the proxy is the element, not a
|
|
237
|
+
// signal around it), everything else a signal.
|
|
238
|
+
const toElement = (item: any) => {
|
|
238
239
|
if (typeof item === 'object' && item !== null) {
|
|
239
|
-
// Recursively wrap nested objects AND arrays in Proxies
|
|
240
240
|
return initializeSignals(item, undefined, context)
|
|
241
241
|
}
|
|
242
242
|
return toSignal(item)
|
|
243
|
-
}
|
|
243
|
+
}
|
|
244
|
+
// Arrays don't get their own signalMap - they use the parent's
|
|
245
|
+
const signals = obj.map(toElement)
|
|
244
246
|
|
|
245
247
|
// List of mutating array methods that should trigger the parent signal
|
|
246
248
|
const mutatingMethods = new Set([
|
|
@@ -354,14 +356,7 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
354
356
|
const deleteCount = args[1] ?? signals.length - start
|
|
355
357
|
const newItems = args.slice(2)
|
|
356
358
|
|
|
357
|
-
|
|
358
|
-
const newSignals = newItems.map((item: any) => {
|
|
359
|
-
if (typeof item === 'object' && item !== null) {
|
|
360
|
-
// Wrap objects/arrays in Proxies (NOT in Signals - the Proxy IS the value)
|
|
361
|
-
return initializeSignals(item, undefined, context)
|
|
362
|
-
}
|
|
363
|
-
return toSignal(item)
|
|
364
|
-
})
|
|
359
|
+
const newSignals = newItems.map(toElement)
|
|
365
360
|
|
|
366
361
|
// Update the signals array (target is signals array)
|
|
367
362
|
const removed = signals.splice(start, deleteCount, ...newSignals)
|
|
@@ -399,14 +394,7 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
399
394
|
let result
|
|
400
395
|
if (propStr === 'push' || propStr === 'unshift') {
|
|
401
396
|
const newItems = args
|
|
402
|
-
|
|
403
|
-
const newSignals = newItems.map((item: any) => {
|
|
404
|
-
if (typeof item === 'object' && item !== null) {
|
|
405
|
-
// Wrap objects/arrays in Proxies (NOT in Signals - the Proxy IS the value)
|
|
406
|
-
return initializeSignals(item, undefined, context)
|
|
407
|
-
}
|
|
408
|
-
return toSignal(item)
|
|
409
|
-
})
|
|
397
|
+
const newSignals = newItems.map(toElement)
|
|
410
398
|
if (propStr === 'push') {
|
|
411
399
|
result = signals.push(...newSignals)
|
|
412
400
|
} else {
|
|
@@ -449,9 +437,11 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
449
437
|
const fillValue = args[0]
|
|
450
438
|
const start = args[1] ?? 0
|
|
451
439
|
const end = args[2] ?? signals.length
|
|
452
|
-
|
|
440
|
+
// A wrap per slot, so no two slots share a signal. An object fill value still reads
|
|
441
|
+
// back as one shared element in every slot, as native fill shares the reference:
|
|
442
|
+
// `toElement` returns the cached proxy for the same object.
|
|
453
443
|
for (let i = start; i < end; i++) {
|
|
454
|
-
signals[i] =
|
|
444
|
+
signals[i] = toElement(fillValue)
|
|
455
445
|
}
|
|
456
446
|
result = signals.length
|
|
457
447
|
} else {
|
|
@@ -493,12 +483,14 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
493
483
|
set(target, prop, value) {
|
|
494
484
|
if (typeof prop === 'string' && !isNaN(Number(prop))) {
|
|
495
485
|
const index = Number(prop)
|
|
496
|
-
|
|
486
|
+
// Assigning past the end (`arr[arr.length] = x`) appends, so it wraps and notifies like push.
|
|
487
|
+
if ((index >= 0 && index < signals.length) || (Number.isInteger(index) && index >= signals.length)) {
|
|
497
488
|
const sig = signals[index]
|
|
498
|
-
|
|
489
|
+
// A primitive over a primitive keeps the element's signal, so `arr.$i` subscribers see it.
|
|
490
|
+
if (isSignal(sig) && (typeof value !== 'object' || value === null)) {
|
|
499
491
|
sig.value = value
|
|
500
492
|
} else {
|
|
501
|
-
signals[index] =
|
|
493
|
+
signals[index] = toElement(value)
|
|
502
494
|
}
|
|
503
495
|
// Trigger parent signal on element assignment (look up when called)
|
|
504
496
|
const parentSignal = arrayParentSignalMap.get(wrapped) || (wrapped as any)._parentSignal
|
|
@@ -520,9 +512,13 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
520
512
|
}
|
|
521
513
|
}
|
|
522
514
|
return true
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (prop === 'length') {
|
|
518
|
+
const previousLength = signals.length
|
|
519
|
+
const result = Reflect.set(target, prop, value)
|
|
520
|
+
// Resizing adds or drops elements without going through a mutator, so it notifies like splice.
|
|
521
|
+
if (signals.length !== previousLength) {
|
|
526
522
|
const parentSignal = arrayParentSignalMap.get(wrapped) || (wrapped as any)._parentSignal
|
|
527
523
|
if (parentSignal) {
|
|
528
524
|
// Notify subscribers directly since the array reference hasn't changed
|
|
@@ -541,8 +537,8 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
541
537
|
;(signal as any).__redrawCallback(parentSignal)
|
|
542
538
|
}
|
|
543
539
|
}
|
|
544
|
-
return true
|
|
545
540
|
}
|
|
541
|
+
return result
|
|
546
542
|
}
|
|
547
543
|
return Reflect.set(target, prop, value)
|
|
548
544
|
},
|
|
@@ -871,11 +867,13 @@ export function state<T extends Record<string, any>>(initial: T, name?: string,
|
|
|
871
867
|
* Mapped type that adds $prop for each key, returning the Signal for that property.
|
|
872
868
|
* - Primitives: $prop => Signal<T[K]>
|
|
873
869
|
* - Nested objects: $prop => Signal<State<T[K]>>
|
|
874
|
-
* - Functions: $prop => ComputedSignal
|
|
870
|
+
* - Functions: $prop => ComputedSignal of the getter's return type
|
|
875
871
|
*/
|
|
876
872
|
export type StateSignals<T extends Record<string, any>> = {
|
|
877
|
-
|
|
878
|
-
|
|
873
|
+
// Only for declared keys: a record's index signature would otherwise gain a `$${string}` twin, and every
|
|
874
|
+
// lookup by a `string` key would read as `Value | Signal<Value>`.
|
|
875
|
+
[K in keyof T as K extends string ? (string extends K ? never : `$${K}`) : never]: T[K] extends (...args: any[]) => infer R
|
|
876
|
+
? ComputedSignal<R>
|
|
879
877
|
: T[K] extends object
|
|
880
878
|
? Signal<State<T[K]>>
|
|
881
879
|
: Signal<T[K]>
|
|
@@ -895,6 +893,27 @@ export type State<T extends Record<string, any>> = T extends (infer Elem)[]
|
|
|
895
893
|
[K in keyof T]: T[K] extends (...args: any[]) => infer R ? R : T[K] extends Record<string, any> ? State<T[K]> : T[K]
|
|
896
894
|
} & StateSignals<T>
|
|
897
895
|
|
|
896
|
+
/**
|
|
897
|
+
* A partial of a state shape at every depth, for the persistence tiers of a Store: each tier fills in
|
|
898
|
+
* part of a nested object (`saved` some keys of `exact`, `temporary` the rest). Arrays and computed
|
|
899
|
+
* getters are replaced wholesale, never merged element-wise.
|
|
900
|
+
*/
|
|
901
|
+
export type DeepPartial<T> = T extends (...args: any[]) => any
|
|
902
|
+
? T
|
|
903
|
+
: T extends readonly unknown[]
|
|
904
|
+
? T
|
|
905
|
+
: T extends object
|
|
906
|
+
? {[K in keyof T]?: DeepPartial<T[K]>}
|
|
907
|
+
: T
|
|
908
|
+
|
|
909
|
+
/**
|
|
910
|
+
* Opens the deferred-computed gate of a state built with `deferComputed` (ADR-0013) and marks its
|
|
911
|
+
* computeds dirty. The gate is a proxy trap rather than a key of the state, so it isn't on `State<T>`.
|
|
912
|
+
*/
|
|
913
|
+
export function allowComputed(stateInstance: State<any>): void {
|
|
914
|
+
;(stateInstance as unknown as {allowComputed?: () => void}).allowComputed?.()
|
|
915
|
+
}
|
|
916
|
+
|
|
898
917
|
/** Function returned by watch() to remove the watcher */
|
|
899
918
|
export type Unwatch = () => void
|
|
900
919
|
|
package/store.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {state, State, updateStateRegistry} from './state'
|
|
1
|
+
import {allowComputed, state, State, updateStateRegistry, type DeepPartial} from './state'
|
|
2
2
|
import {serializeStore, deserializeStore} from './render/ssrState'
|
|
3
3
|
|
|
4
4
|
// Helper function to restore computed properties (same as in ssrState.ts)
|
|
@@ -143,11 +143,11 @@ let storeInstanceCounter = 0
|
|
|
143
143
|
export class Store<T extends Record<string, any> = Record<string, any>> {
|
|
144
144
|
private stateInstance: State<T>
|
|
145
145
|
private templates = {
|
|
146
|
-
saved: {} as
|
|
147
|
-
temporary: {} as
|
|
148
|
-
tab: {} as
|
|
149
|
-
session: {} as
|
|
150
|
-
cookie: {} as
|
|
146
|
+
saved: {} as DeepPartial<T>,
|
|
147
|
+
temporary: {} as DeepPartial<T>,
|
|
148
|
+
tab: {} as DeepPartial<T>,
|
|
149
|
+
session: {} as DeepPartial<T>,
|
|
150
|
+
cookie: {} as DeepPartial<T>,
|
|
151
151
|
}
|
|
152
152
|
private lookup_verify_interval: number | null = null
|
|
153
153
|
private lookup_ttl: number
|
|
@@ -193,15 +193,15 @@ export class Store<T extends Record<string, any> = Record<string, any>> {
|
|
|
193
193
|
* (e.g. after $s, context, or route are ready) so computeds that depend on them can run.
|
|
194
194
|
*/
|
|
195
195
|
ready(): void {
|
|
196
|
-
|
|
196
|
+
allowComputed(this.stateInstance)
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
200
|
* Merge deep on object `state`, but only the key/values in `blueprint`.
|
|
201
201
|
*/
|
|
202
|
-
blueprint(state: T, blueprint:
|
|
202
|
+
blueprint(state: T, blueprint: DeepPartial<T>): DeepPartial<T> {
|
|
203
203
|
if (state == null || typeof state !== 'object') {
|
|
204
|
-
return {} as
|
|
204
|
+
return {} as DeepPartial<T>
|
|
205
205
|
}
|
|
206
206
|
const result: any = {}
|
|
207
207
|
for (const key of Object.keys(blueprint)) {
|
|
@@ -227,7 +227,7 @@ export class Store<T extends Record<string, any> = Record<string, any>> {
|
|
|
227
227
|
result[key] = stateValue
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
-
return result as
|
|
230
|
+
return result as DeepPartial<T>
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
clean_lookup() {
|
|
@@ -297,11 +297,11 @@ export class Store<T extends Record<string, any> = Record<string, any>> {
|
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
load(
|
|
300
|
-
saved:
|
|
301
|
-
temporary:
|
|
302
|
-
tab:
|
|
303
|
-
session:
|
|
304
|
-
cookie:
|
|
300
|
+
saved: DeepPartial<T>,
|
|
301
|
+
temporary: DeepPartial<T>,
|
|
302
|
+
tab: DeepPartial<T> = {} as DeepPartial<T>,
|
|
303
|
+
session: DeepPartial<T> = {} as DeepPartial<T>,
|
|
304
|
+
cookie: DeepPartial<T> = {} as DeepPartial<T>,
|
|
305
305
|
) {
|
|
306
306
|
const restored_state = {
|
|
307
307
|
tab: this.get_tab_storage(this.tabStorageKey),
|