stateshape 0.2.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/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/index.cjs +517 -0
- package/dist/index.d.ts +268 -0
- package/dist/index.mjs +506 -0
- package/index.ts +25 -0
- package/package.json +42 -0
- package/src/EventEmitter.ts +72 -0
- package/src/PersistentState.ts +99 -0
- package/src/Route.ts +223 -0
- package/src/State.ts +101 -0
- package/src/URLState.ts +143 -0
- package/src/isState.ts +20 -0
- package/src/types/EventCallback.ts +1 -0
- package/src/types/EventCallbackMap.ts +5 -0
- package/src/types/LinkElement.ts +1 -0
- package/src/types/LocationObject.ts +11 -0
- package/src/types/LocationPattern.ts +6 -0
- package/src/types/LocationValue.ts +6 -0
- package/src/types/MatchHandler.ts +6 -0
- package/src/types/MatchState.ts +22 -0
- package/src/types/NavigationOptions.ts +10 -0
- package/src/types/PersistentStorage.ts +4 -0
- package/src/types/URLComponents.ts +4 -0
- package/src/types/URLConfig.ts +5 -0
- package/src/types/URLData.ts +10 -0
- package/src/types/URLSchema.ts +4 -0
- package/src/utils/compileURL.ts +27 -0
- package/src/utils/getNavigationOptions.ts +15 -0
- package/src/utils/isLocationObject.ts +11 -0
- package/src/utils/isRouteEvent.ts +11 -0
- package/src/utils/matchURL.ts +99 -0
- package/tsconfig.json +16 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
type EventCallback<T> = (payload: T) => boolean | undefined | void;
|
|
4
|
+
|
|
5
|
+
type EventCallbackMap<Map extends Record<string, unknown>> = Partial<{ [K in keyof Map]: Set<EventCallback<Map[K]>> }>;
|
|
6
|
+
|
|
7
|
+
declare class EventEmitter<P extends Record<string, unknown> = Record<string, void>> {
|
|
8
|
+
_callbacks: EventCallbackMap<P>;
|
|
9
|
+
_active: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Adds an event handler.
|
|
12
|
+
*
|
|
13
|
+
* Returns an unsubscription function. Once it's invoked, the given
|
|
14
|
+
* `callback` is removed and no longer called in response to the event.
|
|
15
|
+
*/
|
|
16
|
+
on<E extends string>(event: E, callback: EventCallback<P[E]>): () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Adds a one-time event handler: once the event is emitted, the callback
|
|
19
|
+
* is called and immediately removed.
|
|
20
|
+
*/
|
|
21
|
+
once<E extends string>(event: E, callback: EventCallback<P[E]>): () => void;
|
|
22
|
+
/**
|
|
23
|
+
* Removes the specified `callback` from the handlers of the given event,
|
|
24
|
+
* and removes all handlers of the given event if `callback` is not
|
|
25
|
+
* specified.
|
|
26
|
+
*/
|
|
27
|
+
off<E extends string>(event: E, callback?: EventCallback<P[E]>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Emits the specified event. Returns `false` if at least one event callback
|
|
30
|
+
* returns `false`, effectively interrupting the callback call chain.
|
|
31
|
+
* Otherwise returns `true`.
|
|
32
|
+
*/
|
|
33
|
+
emit<E extends string>(event: E, payload?: P[E]): boolean;
|
|
34
|
+
get active(): boolean;
|
|
35
|
+
start(): void;
|
|
36
|
+
stop(): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type StateUpdate<T> = (value: T) => T;
|
|
40
|
+
type StateUpdatePayload<T> = {
|
|
41
|
+
previous: T;
|
|
42
|
+
current: T;
|
|
43
|
+
};
|
|
44
|
+
type StatePayloadMap<T> = Record<string, void> & {
|
|
45
|
+
update: StateUpdatePayload<T>;
|
|
46
|
+
set: StateUpdatePayload<T>;
|
|
47
|
+
start: void;
|
|
48
|
+
stop: void;
|
|
49
|
+
};
|
|
50
|
+
type StateOptions = {
|
|
51
|
+
/**
|
|
52
|
+
* Whether to call `start()` at initialization.
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
autoStart?: boolean;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Data container allowing for subscription to its updates.
|
|
59
|
+
*/
|
|
60
|
+
declare class State<T, P extends StatePayloadMap<T> = StatePayloadMap<T>> extends EventEmitter<P> {
|
|
61
|
+
_value: T;
|
|
62
|
+
_revision: number;
|
|
63
|
+
_active: boolean;
|
|
64
|
+
_queue: (() => void)[];
|
|
65
|
+
constructor(value: T, options?: StateOptions);
|
|
66
|
+
_init(): void;
|
|
67
|
+
_call(callback: () => void): void;
|
|
68
|
+
on<E extends string>(event: E, callback: EventCallback<P[E]>): () => void;
|
|
69
|
+
getValue(): T;
|
|
70
|
+
/**
|
|
71
|
+
* Updates the state value.
|
|
72
|
+
*
|
|
73
|
+
* @param update - A new value or an update function `(value) => nextValue`
|
|
74
|
+
* that returns a new state value based on the current state value.
|
|
75
|
+
*/
|
|
76
|
+
setValue(update: T | StateUpdate<T>): void;
|
|
77
|
+
_resolveValue(update: T | StateUpdate<T>): T;
|
|
78
|
+
_assignValue(value: T): void;
|
|
79
|
+
get revision(): number;
|
|
80
|
+
start(): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Serves as an alternative to `instanceof State` which can lead to a false
|
|
85
|
+
* negative when `State` comes from a transitive dependency.
|
|
86
|
+
*/
|
|
87
|
+
declare function isState<T, P extends StatePayloadMap<T> = StatePayloadMap<T>>(x: unknown): x is State<T, P>;
|
|
88
|
+
|
|
89
|
+
type PersistentStorage<T> = {
|
|
90
|
+
read: () => T | null | Promise<T | null>;
|
|
91
|
+
write?: (value: T) => void | Promise<void>;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type StorageEntryOptions<T> = {
|
|
95
|
+
key: string;
|
|
96
|
+
session?: boolean;
|
|
97
|
+
serialize?: (value: T) => string;
|
|
98
|
+
deserialize?: (serializedValue: string) => T;
|
|
99
|
+
};
|
|
100
|
+
declare function getStorageEntry<T>({
|
|
101
|
+
key,
|
|
102
|
+
session,
|
|
103
|
+
serialize,
|
|
104
|
+
deserialize
|
|
105
|
+
}: StorageEntryOptions<T>): PersistentStorage<T>;
|
|
106
|
+
type PersistentStatePayloadMap<T> = StatePayloadMap<T> & {
|
|
107
|
+
sync: void;
|
|
108
|
+
synconce: void;
|
|
109
|
+
effect: void;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* A container for data persistent across page reloads.
|
|
113
|
+
*/
|
|
114
|
+
declare class PersistentState<T, P extends PersistentStatePayloadMap<T> = PersistentStatePayloadMap<T>> extends State<T, P> {
|
|
115
|
+
/**
|
|
116
|
+
* @param value - Initial state value.
|
|
117
|
+
* @param options - Either of the following:
|
|
118
|
+
* - A set of browser storage settings: `key` points to the target browser
|
|
119
|
+
* storage key where the state value should be saved; `session` set to `true`
|
|
120
|
+
* signals to use `sessionStorage` instead of `localStorage`, with the latter
|
|
121
|
+
* being the default; the optional `serialize` and `deserialize` define the
|
|
122
|
+
* way the state value is saved to and restored from the browser storage
|
|
123
|
+
* entry (default: `JSON.stringify` and `JSON.parse` respectively).
|
|
124
|
+
* - A storage singleton with a `read` and an optional `write` method
|
|
125
|
+
* (synchronous or asynchronous).
|
|
126
|
+
*/
|
|
127
|
+
constructor(value: T, options: (StorageEntryOptions<T> | PersistentStorage<T>) & StateOptions);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type URLComponents = {
|
|
131
|
+
params?: Record<string, unknown> | undefined;
|
|
132
|
+
query?: Record<string, unknown> | undefined;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type URLSchema = StandardSchemaV1<URLComponents>;
|
|
136
|
+
|
|
137
|
+
type LocationObject = {
|
|
138
|
+
_schema: URLSchema | undefined;
|
|
139
|
+
exec: (x: string) => URLComponents | null;
|
|
140
|
+
compile: (x: any) => string;
|
|
141
|
+
toString: () => string;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
type URLConfigShape = {
|
|
145
|
+
strict?: boolean;
|
|
146
|
+
};
|
|
147
|
+
interface URLConfig extends URLConfigShape {}
|
|
148
|
+
|
|
149
|
+
type LocationValue = URLConfig["strict"] extends true ? LocationObject | undefined : string | LocationObject | undefined;
|
|
150
|
+
|
|
151
|
+
type LocationPattern = URLConfig["strict"] extends true ? LocationValue | LocationValue[] : LocationValue | RegExp | (LocationValue | RegExp)[];
|
|
152
|
+
|
|
153
|
+
type MatchState<P extends LocationPattern> = {
|
|
154
|
+
ok: boolean;
|
|
155
|
+
href: string;
|
|
156
|
+
params: P extends {
|
|
157
|
+
_schema: URLSchema;
|
|
158
|
+
} ? StandardSchemaV1.InferOutput<P["_schema"]> extends {
|
|
159
|
+
params?: Record<string, unknown>;
|
|
160
|
+
} ? StandardSchemaV1.InferOutput<P["_schema"]>["params"] : Record<string, never> : Record<string, string | undefined>;
|
|
161
|
+
query: P extends {
|
|
162
|
+
_schema: URLSchema;
|
|
163
|
+
} ? StandardSchemaV1.InferOutput<P["_schema"]> extends {
|
|
164
|
+
query?: Record<string, unknown>;
|
|
165
|
+
} ? StandardSchemaV1.InferOutput<P["_schema"]>["query"] : Record<string, never> : Record<string, string | undefined>;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
type MatchHandler<P extends LocationPattern, T> = (payload: MatchState<P>) => T;
|
|
169
|
+
|
|
170
|
+
type NavigationOptions<Href = string> = {
|
|
171
|
+
target?: string;
|
|
172
|
+
href?: Href;
|
|
173
|
+
referrer?: Href;
|
|
174
|
+
spa?: "auto" | "off" | undefined;
|
|
175
|
+
history?: "push" | "replace" | undefined;
|
|
176
|
+
scroll?: "auto" | "off" | undefined;
|
|
177
|
+
id?: string;
|
|
178
|
+
source?: "popstate" | undefined;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
type URLData<T extends LocationValue = LocationValue> = T extends {
|
|
182
|
+
_schema: URLSchema;
|
|
183
|
+
} ? StandardSchemaV1.InferOutput<T["_schema"]> : URLComponents;
|
|
184
|
+
|
|
185
|
+
type URLStatePayloadMap = StatePayloadMap<string> & {
|
|
186
|
+
navigationstart: NavigationOptions;
|
|
187
|
+
navigation: NavigationOptions;
|
|
188
|
+
navigationcomplete: NavigationOptions;
|
|
189
|
+
};
|
|
190
|
+
declare class URLState extends State<string, URLStatePayloadMap> {
|
|
191
|
+
constructor(href?: string | null, options?: StateOptions);
|
|
192
|
+
_init(): void;
|
|
193
|
+
on<E extends string>(event: E, callback: EventCallback<URLStatePayloadMap[E]>, invokeImmediately?: boolean): () => void;
|
|
194
|
+
getValue(): string;
|
|
195
|
+
setValue(update: string | StateUpdate<string>, options?: NavigationOptions): void;
|
|
196
|
+
_transition(options?: NavigationOptions): boolean | void | undefined;
|
|
197
|
+
_complete(options?: NavigationOptions): boolean | void | undefined;
|
|
198
|
+
toValue(x: string): string;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
type ContainerElement = Document | Element | null | undefined;
|
|
202
|
+
type ElementCollection = (string | Node)[] | HTMLCollection | NodeList;
|
|
203
|
+
type ObservedElement = string | Node | (string | Node)[] | HTMLCollection | NodeList;
|
|
204
|
+
declare class Route extends URLState {
|
|
205
|
+
_clicks: Set<(event: MouseEvent) => void>;
|
|
206
|
+
constructor(href?: LocationValue | null, options?: StateOptions);
|
|
207
|
+
_init(): void;
|
|
208
|
+
observe(container: ContainerElement | (() => ContainerElement), elements?: ObservedElement): () => void;
|
|
209
|
+
navigate(options?: NavigationOptions<LocationValue>): void;
|
|
210
|
+
assign(url: LocationValue): void;
|
|
211
|
+
replace(url: LocationValue): void;
|
|
212
|
+
reload(): void;
|
|
213
|
+
go(delta: number): void;
|
|
214
|
+
back(): void;
|
|
215
|
+
forward(): void;
|
|
216
|
+
get href(): string;
|
|
217
|
+
set href(value: LocationValue);
|
|
218
|
+
get pathname(): string;
|
|
219
|
+
set pathname(value: LocationValue);
|
|
220
|
+
get search(): string;
|
|
221
|
+
set search(value: string | URLSearchParams);
|
|
222
|
+
get hash(): string;
|
|
223
|
+
set hash(value: string);
|
|
224
|
+
toString(): string;
|
|
225
|
+
/**
|
|
226
|
+
* Matches the current location against `urlPattern`.
|
|
227
|
+
*/
|
|
228
|
+
match<P extends LocationPattern>(urlPattern: P): MatchState<P>;
|
|
229
|
+
/**
|
|
230
|
+
* Compiles `urlPattern` to a URL string by filling out the parameters
|
|
231
|
+
* based on `data`.
|
|
232
|
+
*/
|
|
233
|
+
compile<T extends LocationValue>(urlPattern: T, data?: URLData<T>): string;
|
|
234
|
+
/**
|
|
235
|
+
* Checks whether `urlPattern` matches the current URL and returns either
|
|
236
|
+
* based on `x` if there is a match, or based on `y` otherwise. (It
|
|
237
|
+
* loosely resembles the ternary conditional operator
|
|
238
|
+
* `matchesPattern ? x : y`.)
|
|
239
|
+
*
|
|
240
|
+
* If the current location matches `urlPattern`, `at(urlPattern, x, y)`
|
|
241
|
+
* returns:
|
|
242
|
+
* - `x`, if `x` is not a function;
|
|
243
|
+
* - `x({ params })`, if `x` is a function, with `params` extracted from
|
|
244
|
+
* the current URL.
|
|
245
|
+
*
|
|
246
|
+
* If the current location doesn't match `urlPattern`, `at(urlPattern, x, y)`
|
|
247
|
+
* returns:
|
|
248
|
+
* - `y`, if `y` is not a function;
|
|
249
|
+
* - `y({ params })`, if `y` is a function, with `params` extracted from
|
|
250
|
+
* the current URL.
|
|
251
|
+
*/
|
|
252
|
+
at<P extends LocationPattern, X>(urlPattern: P, matchOutput: X | MatchHandler<P, X>): X | undefined;
|
|
253
|
+
at<P extends LocationPattern, X, Y>(urlPattern: P, matchOutput: X | MatchHandler<P, X>, mismatchOutput: Y | MatchHandler<P, Y>): X | Y;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
type LinkElement = HTMLAnchorElement | HTMLAreaElement;
|
|
257
|
+
|
|
258
|
+
declare function compileURL<T extends LocationValue>(urlPattern: T, data?: URLData<T>): string;
|
|
259
|
+
|
|
260
|
+
declare function getNavigationOptions(element: LinkElement): NavigationOptions;
|
|
261
|
+
|
|
262
|
+
declare function isLocationObject(x: unknown): x is LocationObject;
|
|
263
|
+
|
|
264
|
+
declare function isRouteEvent(event: unknown): boolean;
|
|
265
|
+
|
|
266
|
+
declare function matchURL<P extends LocationPattern>(pattern: P, href: string): MatchState<P>;
|
|
267
|
+
|
|
268
|
+
export { ContainerElement, ElementCollection, EventCallback, EventCallbackMap, EventEmitter, LinkElement, LocationObject, LocationPattern, LocationValue, MatchHandler, MatchState, NavigationOptions, ObservedElement, PersistentState, PersistentStatePayloadMap, PersistentStorage, Route, State, StateOptions, StatePayloadMap, StateUpdate, StateUpdatePayload, StorageEntryOptions, URLComponents, URLConfig, URLData, URLSchema, URLState, URLStatePayloadMap, compileURL, getNavigationOptions, getStorageEntry, isLocationObject, isRouteEvent, isState, matchURL };
|