ctrl-fx 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/chunk-BDTTV33M.js +4050 -0
- package/dist/chunk-EKBLRHWK.js +916 -0
- package/dist/chunk-OSIRHKDB.js +1812 -0
- package/dist/chunk-PKBMQBKP.js +7 -0
- package/dist/chunk-XICUXW4T.js +252 -0
- package/dist/db/index.d.ts +218 -16
- package/dist/db/index.js +53 -19
- package/dist/dom/index.d.ts +2 -248
- package/dist/dom/index.js +30 -266
- package/dist/effects.d.ts +2 -580
- package/dist/effects.js +111 -1556
- package/dist/index-DeEjNrg-.d.ts +1399 -0
- package/dist/index.d.ts +2 -41
- package/dist/index.js +18 -78
- package/dist/router.d.ts +11 -12
- package/dist/router.js +57 -68
- package/dist/testing.d.ts +67 -60
- package/dist/testing.js +46 -158
- package/dist/webcomponent.d.ts +7 -4
- package/dist/webcomponent.js +48 -40
- package/package.json +4 -3
- package/dist/clipboard.d.ts +0 -7
- package/dist/clipboard.d.ts.map +0 -1
- package/dist/clipboard.js +0 -3
- package/dist/db/effects.d.ts +0 -78
- package/dist/db/effects.d.ts.map +0 -1
- package/dist/db/effects.js +0 -98
- package/dist/db/errors.d.ts +0 -21
- package/dist/db/errors.d.ts.map +0 -1
- package/dist/db/errors.js +0 -13
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/keypath.d.ts +0 -40
- package/dist/db/keypath.d.ts.map +0 -1
- package/dist/db/keypath.js +0 -20
- package/dist/db/setup.d.ts +0 -83
- package/dist/db/setup.d.ts.map +0 -1
- package/dist/db/setup.js +0 -100
- package/dist/db/testdb.d.ts +0 -19
- package/dist/db/testdb.d.ts.map +0 -1
- package/dist/db/testdb.js +0 -34
- package/dist/dom/attrs.d.ts +0 -67
- package/dist/dom/attrs.d.ts.map +0 -1
- package/dist/dom/attrs.js +0 -154
- package/dist/dom/components.d.ts +0 -43
- package/dist/dom/components.d.ts.map +0 -1
- package/dist/dom/components.js +0 -86
- package/dist/dom/elems.d.ts +0 -121
- package/dist/dom/elems.d.ts.map +0 -1
- package/dist/dom/elems.js +0 -52
- package/dist/dom/events.d.ts +0 -232
- package/dist/dom/events.d.ts.map +0 -1
- package/dist/dom/events.js +0 -289
- package/dist/dom/index.d.ts.map +0 -1
- package/dist/dom/nodeid.d.ts +0 -9
- package/dist/dom/nodeid.d.ts.map +0 -1
- package/dist/dom/nodeid.js +0 -27
- package/dist/dom/svg.d.ts +0 -23
- package/dist/dom/svg.d.ts.map +0 -1
- package/dist/dom/svg.js +0 -1
- package/dist/dom/views.d.ts +0 -60
- package/dist/dom/views.d.ts.map +0 -1
- package/dist/dom/views.js +0 -154
- package/dist/effects.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/internal/clipboard.d.ts +0 -5
- package/dist/internal/clipboard.d.ts.map +0 -1
- package/dist/internal/clipboard.js +0 -33
- package/dist/internal/cmpmgr.d.ts +0 -46
- package/dist/internal/cmpmgr.d.ts.map +0 -1
- package/dist/internal/cmpmgr.js +0 -561
- package/dist/internal/dbmgr.d.ts +0 -11
- package/dist/internal/dbmgr.d.ts.map +0 -1
- package/dist/internal/dbmgr.js +0 -200
- package/dist/internal/dominterpreter.d.ts +0 -5
- package/dist/internal/dominterpreter.d.ts.map +0 -1
- package/dist/internal/dominterpreter.js +0 -337
- package/dist/internal/eventmgr.d.ts +0 -41
- package/dist/internal/eventmgr.d.ts.map +0 -1
- package/dist/internal/eventmgr.js +0 -696
- package/dist/internal/index.d.ts +0 -19
- package/dist/internal/index.d.ts.map +0 -1
- package/dist/internal/index.js +0 -38
- package/dist/internal/interpreter.d.ts +0 -10
- package/dist/internal/interpreter.d.ts.map +0 -1
- package/dist/internal/interpreter.js +0 -1
- package/dist/internal/locutils.d.ts +0 -4
- package/dist/internal/locutils.d.ts.map +0 -1
- package/dist/internal/locutils.js +0 -22
- package/dist/internal/net.d.ts +0 -4
- package/dist/internal/net.d.ts.map +0 -1
- package/dist/internal/net.js +0 -64
- package/dist/internal/realdom.d.ts +0 -249
- package/dist/internal/realdom.d.ts.map +0 -1
- package/dist/internal/realdom.js +0 -1
- package/dist/internal/styleregistry.d.ts +0 -6
- package/dist/internal/styleregistry.d.ts.map +0 -1
- package/dist/internal/styleregistry.js +0 -18
- package/dist/internal/taskreg.d.ts +0 -9
- package/dist/internal/taskreg.d.ts.map +0 -1
- package/dist/internal/taskreg.js +0 -28
- package/dist/internal/testing.d.ts +0 -12
- package/dist/internal/testing.d.ts.map +0 -1
- package/dist/internal/testing.js +0 -974
- package/dist/internal/testinginterpreter.d.ts +0 -10
- package/dist/internal/testinginterpreter.d.ts.map +0 -1
- package/dist/internal/testinginterpreter.js +0 -646
- package/dist/internal/vdom.d.ts +0 -93
- package/dist/internal/vdom.d.ts.map +0 -1
- package/dist/internal/vdom.js +0 -470
- package/dist/json/index.d.ts +0 -5
- package/dist/json/index.d.ts.map +0 -1
- package/dist/json/index.js +0 -2
- package/dist/json/validation.d.ts +0 -28
- package/dist/json/validation.d.ts.map +0 -1
- package/dist/json/validation.js +0 -8
- package/dist/net/fragment.d.ts +0 -10
- package/dist/net/fragment.d.ts.map +0 -1
- package/dist/net/fragment.js +0 -27
- package/dist/net/index.d.ts +0 -42
- package/dist/net/index.d.ts.map +0 -1
- package/dist/net/index.js +0 -60
- package/dist/net/location.d.ts +0 -21
- package/dist/net/location.d.ts.map +0 -1
- package/dist/net/location.js +0 -41
- package/dist/net/path.d.ts +0 -12
- package/dist/net/path.d.ts.map +0 -1
- package/dist/net/path.js +0 -29
- package/dist/net/queryparam.d.ts +0 -10
- package/dist/net/queryparam.d.ts.map +0 -1
- package/dist/net/queryparam.js +0 -34
- package/dist/router.d.ts.map +0 -1
- package/dist/scroll.d.ts +0 -7
- package/dist/scroll.d.ts.map +0 -1
- package/dist/scroll.js +0 -3
- package/dist/testing.d.ts.map +0 -1
- package/dist/utils/apply.d.ts +0 -9
- package/dist/utils/apply.d.ts.map +0 -1
- package/dist/utils/apply.js +0 -10
- package/dist/utils/index.d.ts +0 -22
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -138
- package/dist/utils/lens.d.ts +0 -18
- package/dist/utils/lens.d.ts.map +0 -1
- package/dist/utils/lens.js +0 -27
- package/dist/utils/match.d.ts +0 -17
- package/dist/utils/match.d.ts.map +0 -1
- package/dist/utils/match.js +0 -28
- package/dist/utils/result.d.ts +0 -47
- package/dist/utils/result.d.ts.map +0 -1
- package/dist/utils/result.js +0 -97
- package/dist/webcomponent.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import { type Effect } from './effects';
|
|
4
|
-
import type { Component } from './dom/components';
|
|
5
|
-
/** Type guard that returns true when `effectOrState` is a plain state value rather than an `Effect`. */
|
|
6
|
-
export declare function isState<State>(effectOrState: Effect<State, never, State> | State): effectOrState is State;
|
|
7
|
-
/** Converts a plain view function and initial state into a `Component`. Used internally by `manageApplication`; prefer `component()` from `ctrl-fx/dom` in application code. */
|
|
8
|
-
export declare function toComponent<State>(app: (state: State) => Node<State, never> | NodeGroup<State, never>, initialState: State | Effect<State, never, State>): Component<State, void, never>;
|
|
9
|
-
/**
|
|
10
|
-
* Mounts a ctrl-fx application into the DOM element with id `mountId` and starts the runtime.
|
|
11
|
-
* Returns a `dispatchEffect` handle for triggering effects from outside the framework
|
|
12
|
-
* (e.g. from a service worker message).
|
|
13
|
-
* @param mountId The id of the mount element. Defaults to `'app'`.
|
|
14
|
-
*/
|
|
15
|
-
export declare function manageApplication<State>(app: (state: State) => Node<State, never> | NodeGroup<State, never>, initialState: State | Effect<State, never, State>, mountId?: string): {
|
|
16
|
-
dispatchEffect: (effect: Effect<State, never, void>) => void;
|
|
17
|
-
};
|
|
18
|
-
/** Width and height in pixels, as reported by a resize observer. */
|
|
19
|
-
export type Dimensions = {
|
|
20
|
-
width: number;
|
|
21
|
-
height: number;
|
|
22
|
-
};
|
|
23
|
-
/** The browser permission state for a feature such as notifications. */
|
|
24
|
-
export interface Permission {
|
|
25
|
-
value: 'default' | 'granted' | 'denied';
|
|
26
|
-
/** Returns true when the permission has been explicitly granted. */
|
|
27
|
-
isGranted(): boolean;
|
|
28
|
-
/** Returns true when the user has not yet been prompted. */
|
|
29
|
-
isDefault(): boolean;
|
|
30
|
-
/** Returns true when the permission has been explicitly denied. */
|
|
31
|
-
isDenied(): boolean;
|
|
32
|
-
}
|
|
33
|
-
/** Constructs a `Permission` value from a raw browser permission string. */
|
|
34
|
-
export declare function permission(value: 'default' | 'granted' | 'denied'): Permission;
|
|
35
|
-
/** A branded string containing a UUID v4. */
|
|
36
|
-
export type Uuid = string & {
|
|
37
|
-
__brand: 'Uuid';
|
|
38
|
-
};
|
|
39
|
-
/** Deterministically derives a UUID-shaped string from `input` by hashing it. Useful for generating stable node identifiers from content. */
|
|
40
|
-
export declare function uuidFromString(input: string): Uuid;
|
|
41
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export { D as Dimensions, P as Permission, U as Uuid, i as isState, m as manageApplication, p as permission, t as toComponent, u as uuidFromString } from './index-DeEjNrg-.js';
|
|
2
|
+
import './db/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,78 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
: initialState;
|
|
20
|
-
const adjustedApp = (state) => {
|
|
21
|
-
const nodeOrNodeGroup = app(state);
|
|
22
|
-
if (isNodeGroup(nodeOrNodeGroup)) {
|
|
23
|
-
return nodeOrNodeGroup;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return nodeGroup(nodeOrNodeGroup);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
return {
|
|
30
|
-
_type: 'Component',
|
|
31
|
-
params: undefined,
|
|
32
|
-
view: adjustedApp,
|
|
33
|
-
initialState() {
|
|
34
|
-
return initialStateEffect;
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Mounts a ctrl-fx application into the DOM element with id `mountId` and starts the runtime.
|
|
40
|
-
* Returns a `dispatchEffect` handle for triggering effects from outside the framework
|
|
41
|
-
* (e.g. from a service worker message).
|
|
42
|
-
* @param mountId The id of the mount element. Defaults to `'app'`.
|
|
43
|
-
*/
|
|
44
|
-
export function manageApplication(app, initialState, mountId = 'app') {
|
|
45
|
-
const component = toComponent(app, initialState);
|
|
46
|
-
return manageComponent(component, mountId, globalThis.window, domInterpreter, realStyleRegistry());
|
|
47
|
-
}
|
|
48
|
-
/** Constructs a `Permission` value from a raw browser permission string. */
|
|
49
|
-
export function permission(value) {
|
|
50
|
-
return {
|
|
51
|
-
value,
|
|
52
|
-
isGranted() {
|
|
53
|
-
return value === 'granted';
|
|
54
|
-
},
|
|
55
|
-
isDefault() {
|
|
56
|
-
return value === 'default';
|
|
57
|
-
},
|
|
58
|
-
isDenied() {
|
|
59
|
-
return value === 'denied';
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
/** Deterministically derives a UUID-shaped string from `input` by hashing it. Useful for generating stable node identifiers from content. */
|
|
64
|
-
export function uuidFromString(input) {
|
|
65
|
-
let hash = 0;
|
|
66
|
-
for (let i = 0; i < input.length; i++) {
|
|
67
|
-
hash = ((hash << 5) - hash + input.charCodeAt(i)) | 0;
|
|
68
|
-
}
|
|
69
|
-
const hex = (hash >>> 0).toString(16).padStart(8, '0');
|
|
70
|
-
const repeated = hex.repeat(4);
|
|
71
|
-
return [
|
|
72
|
-
repeated.slice(0, 8),
|
|
73
|
-
repeated.slice(8, 12),
|
|
74
|
-
repeated.slice(12, 16),
|
|
75
|
-
repeated.slice(16, 20),
|
|
76
|
-
repeated.slice(20, 32),
|
|
77
|
-
].join('-');
|
|
78
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
isState,
|
|
3
|
+
manageApplication,
|
|
4
|
+
permission,
|
|
5
|
+
toComponent,
|
|
6
|
+
uuidFromString
|
|
7
|
+
} from "./chunk-BDTTV33M.js";
|
|
8
|
+
import "./chunk-EKBLRHWK.js";
|
|
9
|
+
import "./chunk-OSIRHKDB.js";
|
|
10
|
+
import "./chunk-XICUXW4T.js";
|
|
11
|
+
import "./chunk-PKBMQBKP.js";
|
|
12
|
+
export {
|
|
13
|
+
isState,
|
|
14
|
+
manageApplication,
|
|
15
|
+
permission,
|
|
16
|
+
toComponent,
|
|
17
|
+
uuidFromString
|
|
18
|
+
};
|
package/dist/router.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export type { EventActions } from './dom/events';
|
|
5
|
-
export type { InternalLocation } from './net/location';
|
|
1
|
+
import { I as InternalLocation, E as Effect, a as EventActions } from './index-DeEjNrg-.js';
|
|
2
|
+
import './db/index.js';
|
|
3
|
+
|
|
6
4
|
/** Named path-segment parameters extracted from a matched route. */
|
|
7
|
-
|
|
5
|
+
type Params = Record<string, string>;
|
|
8
6
|
/** A map of URL patterns to handler functions. Pattern keys use `:param` syntax for named path segments. */
|
|
9
|
-
|
|
7
|
+
type RouteMap<Route> = {
|
|
10
8
|
[pattern: string]: (params: Params) => Route;
|
|
11
9
|
};
|
|
12
10
|
/**
|
|
@@ -17,24 +15,25 @@ export type RouteMap<Route> = {
|
|
|
17
15
|
* const match = router({ '/': () => 'home', '/users/:id': ({ id }) => `user-${id}` })
|
|
18
16
|
* ```
|
|
19
17
|
*/
|
|
20
|
-
|
|
18
|
+
declare function router<Route>(routes: RouteMap<Route>): (location: InternalLocation) => Route | null;
|
|
21
19
|
/**
|
|
22
20
|
* An effect describing a `history.pushState` to `path`, suitable for use as an `onClick` handler on an `<a>` element.
|
|
23
21
|
* Produces `{ preventDefault: true }` to suppress the default browser navigation.
|
|
24
22
|
*/
|
|
25
|
-
|
|
23
|
+
declare function link<State, Event>(path: string): Effect<State, Event, EventActions>;
|
|
26
24
|
/** An effect describing a `history.pushState` to `path`. Use in effect chains or button handlers. */
|
|
27
|
-
|
|
25
|
+
declare function navigate<State, Event>(path: string): Effect<State, Event, void>;
|
|
28
26
|
/**
|
|
29
27
|
* Bundled router that strips `options.basePath` before matching and prepends it before navigating.
|
|
30
28
|
* Use when your app is mounted at a sub-path (e.g. a GitHub Pages subdirectory).
|
|
31
29
|
* Returns a `{ match, link, navigate }` object.
|
|
32
30
|
*/
|
|
33
|
-
|
|
31
|
+
declare function createRouter<Route>(routes: RouteMap<Route>, options?: {
|
|
34
32
|
basePath?: string;
|
|
35
33
|
}): {
|
|
36
34
|
match(location: InternalLocation): Route | null;
|
|
37
35
|
link<State, Event>(path: string): Effect<State, Event, EventActions>;
|
|
38
36
|
navigate<State, Event>(path: string): Effect<State, Event, void>;
|
|
39
37
|
};
|
|
40
|
-
|
|
38
|
+
|
|
39
|
+
export { EventActions, InternalLocation, type Params, type RouteMap, createRouter, link, navigate, router };
|
package/dist/router.js
CHANGED
|
@@ -1,77 +1,66 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
async,
|
|
3
|
+
parseInternalLocation,
|
|
4
|
+
pushState
|
|
5
|
+
} from "./chunk-OSIRHKDB.js";
|
|
6
|
+
import "./chunk-PKBMQBKP.js";
|
|
7
|
+
|
|
8
|
+
// src/router.ts
|
|
3
9
|
function compile(routes) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
return Object.entries(routes).map(([pattern, handler]) => ({
|
|
11
|
+
segments: pattern.split("/"),
|
|
12
|
+
handler
|
|
13
|
+
}));
|
|
8
14
|
}
|
|
9
15
|
function matchRoute(compiled, location) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (matched)
|
|
27
|
-
return handler(params);
|
|
16
|
+
const pathSegs = location.path.elems;
|
|
17
|
+
for (const { segments, handler } of compiled) {
|
|
18
|
+
if (segments.length !== pathSegs.length) continue;
|
|
19
|
+
const params = {};
|
|
20
|
+
let matched = true;
|
|
21
|
+
for (let i = 0; i < segments.length; i++) {
|
|
22
|
+
const seg = segments[i];
|
|
23
|
+
if (seg.startsWith(":")) {
|
|
24
|
+
params[seg.slice(1)] = pathSegs[i];
|
|
25
|
+
} else if (seg.toLowerCase() !== pathSegs[i].toLowerCase()) {
|
|
26
|
+
matched = false;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
28
29
|
}
|
|
29
|
-
return
|
|
30
|
+
if (matched) return handler(params);
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
*
|
|
35
|
-
* ```ts
|
|
36
|
-
* const match = router({ '/': () => 'home', '/users/:id': ({ id }) => `user-${id}` })
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
export function router(routes) {
|
|
40
|
-
const compiled = compile(routes);
|
|
41
|
-
return location => matchRoute(compiled, location);
|
|
34
|
+
function router(routes) {
|
|
35
|
+
const compiled = compile(routes);
|
|
36
|
+
return (location) => matchRoute(compiled, location);
|
|
42
37
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
export function link(path) {
|
|
48
|
-
return async(pushState(parseInternalLocation(path)), 0).as({
|
|
49
|
-
preventDefault: true,
|
|
50
|
-
});
|
|
38
|
+
function link(path) {
|
|
39
|
+
return async(pushState(parseInternalLocation(path)), 0).as({
|
|
40
|
+
preventDefault: true
|
|
41
|
+
});
|
|
51
42
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return pushState(parseInternalLocation(path));
|
|
43
|
+
function navigate(path) {
|
|
44
|
+
return pushState(parseInternalLocation(path));
|
|
55
45
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return null;
|
|
71
|
-
const relative = fullPath.slice(base.length) || '/';
|
|
72
|
-
return matchRoute(compiled, parseInternalLocation(relative));
|
|
73
|
-
},
|
|
74
|
-
link: (path) => link(base + path),
|
|
75
|
-
navigate: (path) => navigate(base + path),
|
|
76
|
-
};
|
|
46
|
+
function createRouter(routes, options) {
|
|
47
|
+
const compiled = compile(routes);
|
|
48
|
+
const base = options?.basePath ?? "";
|
|
49
|
+
return {
|
|
50
|
+
match(location) {
|
|
51
|
+
if (!base) return matchRoute(compiled, location);
|
|
52
|
+
const fullPath = location.path.elems.join("/");
|
|
53
|
+
if (!fullPath.startsWith(base)) return null;
|
|
54
|
+
const relative = fullPath.slice(base.length) || "/";
|
|
55
|
+
return matchRoute(compiled, parseInternalLocation(relative));
|
|
56
|
+
},
|
|
57
|
+
link: (path) => link(base + path),
|
|
58
|
+
navigate: (path) => navigate(base + path)
|
|
59
|
+
};
|
|
77
60
|
}
|
|
61
|
+
export {
|
|
62
|
+
createRouter,
|
|
63
|
+
link,
|
|
64
|
+
navigate,
|
|
65
|
+
router
|
|
66
|
+
};
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,45 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { A as Attr, H as HttpRequest, R as Result, b as HttpResponse, c as RequestError, d as HttpError, I as InternalLocation, S as ScrollOptions, N as NodeGroup, e as Node, E as Effect, C as Component } from './index-DeEjNrg-.js';
|
|
2
|
+
export { f as ResponseBody, g as failure, s as success } from './index-DeEjNrg-.js';
|
|
3
|
+
import { KeyPath, JsonValue, DbName, ObjectStore } from './db/index.js';
|
|
4
|
+
|
|
5
|
+
type NonEmptyArray<A> = [A, ...A[]];
|
|
6
|
+
|
|
7
|
+
type DbStoreSnapshot = {
|
|
8
|
+
readonly keyPath: KeyPath;
|
|
9
|
+
readonly records: ReadonlyMap<string, JsonValue>;
|
|
10
|
+
readonly autoIncrementCounter: number;
|
|
11
|
+
};
|
|
12
|
+
declare class TestDatabaseData {
|
|
13
|
+
readonly _databases: ReadonlyMap<string, ReadonlyMap<string, DbStoreSnapshot>>;
|
|
14
|
+
constructor(databases: ReadonlyMap<string, ReadonlyMap<string, DbStoreSnapshot>>);
|
|
15
|
+
records(db: DbName, store: ObjectStore): readonly JsonValue[];
|
|
16
|
+
getByKey(db: DbName, store: ObjectStore, key: IDBValidKey): JsonValue | undefined;
|
|
17
|
+
size(db: DbName, store: ObjectStore): number;
|
|
18
|
+
hasDatabase(db: DbName): boolean;
|
|
19
|
+
hasStore(db: DbName, store: ObjectStore): boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type DownloadRecord = {
|
|
17
23
|
readonly filename: string;
|
|
18
24
|
readonly content: string;
|
|
19
25
|
readonly contentType: string;
|
|
20
26
|
};
|
|
21
|
-
|
|
27
|
+
type BroadcastSentRecord = {
|
|
22
28
|
readonly channel: string;
|
|
23
29
|
readonly message: unknown;
|
|
24
30
|
};
|
|
25
|
-
|
|
31
|
+
type SetAppBadge = {
|
|
26
32
|
_type: 'SetAppBadge';
|
|
27
33
|
count: number;
|
|
28
34
|
};
|
|
29
|
-
|
|
35
|
+
type ClearAppBadge = {
|
|
30
36
|
_type: 'ClearAppBadge';
|
|
31
37
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
type AppBadgeOperation = SetAppBadge | ClearAppBadge;
|
|
39
|
+
declare const clearAppBadge: ClearAppBadge;
|
|
40
|
+
declare function setAppBadge(count: number): SetAppBadge;
|
|
41
|
+
declare function appBadgeCount(operations: readonly AppBadgeOperation[]): number;
|
|
42
|
+
type HttpInteraction = {
|
|
37
43
|
readonly request: HttpRequest;
|
|
38
44
|
readonly response: Result<HttpResponse, RequestError | HttpError>;
|
|
39
45
|
};
|
|
40
|
-
|
|
46
|
+
type HttpHandler = (request: HttpRequest, prior: readonly HttpInteraction[]) => Result<HttpResponse, RequestError | HttpError>;
|
|
41
47
|
/** Configuration passed to `testApplication`/`testComponent` to control how side effects behave during tests. */
|
|
42
|
-
|
|
48
|
+
type TestConfig = {
|
|
43
49
|
readonly http: {
|
|
44
50
|
/** Called for each HTTP request. Throw or return a failure Result to simulate errors. */
|
|
45
51
|
readonly handler: HttpHandler;
|
|
@@ -54,18 +60,18 @@ export type TestConfig = {
|
|
|
54
60
|
};
|
|
55
61
|
};
|
|
56
62
|
/** Creates a TestConfig that throws on any HTTP request. */
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
declare function defaultTestConfig(): TestConfig;
|
|
64
|
+
type ConfirmInteraction = {
|
|
59
65
|
message: string;
|
|
60
66
|
response: boolean;
|
|
61
67
|
};
|
|
62
|
-
|
|
68
|
+
type PromptInteraction = {
|
|
63
69
|
message: string;
|
|
64
70
|
default: string | undefined;
|
|
65
71
|
response: string | null;
|
|
66
72
|
};
|
|
67
73
|
/** Snapshot of every observable side effect that occurred during a test run. */
|
|
68
|
-
|
|
74
|
+
type TestData<Custom = {}> = {
|
|
69
75
|
readonly window: {
|
|
70
76
|
readonly alerts: readonly any[];
|
|
71
77
|
readonly confirms: readonly ConfirmInteraction[];
|
|
@@ -119,66 +125,66 @@ export type TestData<Custom = {}> = {
|
|
|
119
125
|
readonly custom: Custom;
|
|
120
126
|
};
|
|
121
127
|
/** Creates an empty TestData, optionally initialising the `custom` field. */
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
declare function newTestData<Custom = {}>(custom?: Custom): TestData<Custom>;
|
|
129
|
+
type TestInput<State, Params, Custom = {}> = {
|
|
124
130
|
state?: State;
|
|
125
131
|
params?: Params;
|
|
126
132
|
testData?: TestData<Custom>;
|
|
127
133
|
};
|
|
128
|
-
|
|
134
|
+
type Click = {
|
|
129
135
|
type: 'Click';
|
|
130
136
|
selector: QuerySelector;
|
|
131
137
|
};
|
|
132
138
|
/** Simulates a click on the element(s) matching `selector`. */
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
declare function click(selector: QuerySelector): Click;
|
|
140
|
+
type AdvanceTime = {
|
|
135
141
|
_type: 'AdvanceTime';
|
|
136
142
|
milliseconds: number;
|
|
137
143
|
};
|
|
138
144
|
/** Advances the test scheduler clock by `milliseconds`, firing any scheduled tasks that come due. */
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
declare function advanceTime(milliseconds: number): AdvanceTime;
|
|
146
|
+
type ReceiveBroadcast = {
|
|
141
147
|
_type: 'ReceiveBroadcast';
|
|
142
148
|
channel: string;
|
|
143
149
|
message: unknown;
|
|
144
150
|
};
|
|
145
151
|
/** Delivers a BroadcastChannel message to any active subscriber on `channel`. */
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
declare function receiveBroadcast(channel: string, message: unknown): ReceiveBroadcast;
|
|
153
|
+
type FireCustomEvent = {
|
|
148
154
|
_type: 'FireCustomEvent';
|
|
149
155
|
selector: QuerySelector;
|
|
150
156
|
eventName: string;
|
|
151
157
|
detail: unknown;
|
|
152
158
|
};
|
|
153
159
|
/** Dispatches a custom DOM event on the element matching `selector`, invoking any `onEvent` handler. */
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
declare function fireCustomEvent(selector: QuerySelector, eventName: string, detail?: unknown): FireCustomEvent;
|
|
161
|
+
type Submit = {
|
|
156
162
|
_type: 'Submit';
|
|
157
163
|
selector: QuerySelector;
|
|
158
164
|
};
|
|
159
165
|
/** Simulates a form submit event on the element(s) matching `selector`. */
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
declare function submit(selector: QuerySelector): Submit;
|
|
167
|
+
type TextInput = {
|
|
162
168
|
_type: 'TextInput';
|
|
163
169
|
selector: QuerySelector;
|
|
164
170
|
value: string;
|
|
165
171
|
};
|
|
166
172
|
/** Simulates an `input` event on the element(s) matching `selector`. */
|
|
167
|
-
|
|
173
|
+
declare function textInput(selector: QuerySelector, value: string): TextInput;
|
|
168
174
|
/** Creates an attribute object `{ name, value }` for use with `findOne(...).attrs.toContainEqual(attr(...))`. */
|
|
169
|
-
|
|
175
|
+
declare function attr(name: string, value: string): {
|
|
170
176
|
name: string;
|
|
171
177
|
value: string;
|
|
172
178
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
179
|
+
type Interaction = Click | AdvanceTime | ReceiveBroadcast | FireCustomEvent | Submit | TextInput;
|
|
180
|
+
|
|
181
|
+
type DomElement = {
|
|
176
182
|
readonly tag: string;
|
|
177
183
|
readonly attrs: readonly Attr[];
|
|
178
184
|
readonly childNodes: readonly DomNode[];
|
|
179
185
|
};
|
|
180
|
-
|
|
181
|
-
|
|
186
|
+
type DomNode = DomElement | string;
|
|
187
|
+
type TestableDom = {
|
|
182
188
|
head: DomElement;
|
|
183
189
|
body: DomElement;
|
|
184
190
|
};
|
|
@@ -188,7 +194,7 @@ export type TestableDom = {
|
|
|
188
194
|
* `TestableComponent` reflecting the state after those interactions, so tests
|
|
189
195
|
* can chain calls to build up complex scenarios step by step.
|
|
190
196
|
*/
|
|
191
|
-
|
|
197
|
+
type TestableComponent<State, Params, Event, Custom = {}> = {
|
|
192
198
|
readonly config: TestConfig;
|
|
193
199
|
readonly state: State;
|
|
194
200
|
readonly data: TestData<Custom>;
|
|
@@ -218,31 +224,32 @@ export type TestableComponent<State, Params, Event, Custom = {}> = {
|
|
|
218
224
|
* component that was created with `component()`. For testing a top-level view
|
|
219
225
|
* function directly, use `testApplication` instead.
|
|
220
226
|
*/
|
|
221
|
-
|
|
227
|
+
declare function testComponent<State, Params, Event, Custom = {}>(component: Component<State, Params, Event>, config?: TestConfig, data?: TestData<Custom>): TestableComponent<State, Params, Event, Custom>;
|
|
222
228
|
/**
|
|
223
229
|
* The main entry point for testing a ctrl-fx application. Wraps a view
|
|
224
230
|
* function and initial state into a `TestableComponent`. Call `.run(...)`
|
|
225
231
|
* with interactions to simulate user actions, then inspect `.state`, `.data`,
|
|
226
232
|
* and the `findOne`/`find` DOM query methods on the result.
|
|
227
233
|
*/
|
|
228
|
-
|
|
229
|
-
|
|
234
|
+
declare function testApplication<State, Custom = {}>(app: (state: State) => NodeGroup<State, never> | Node<State, never>, initialState: State | Effect<State, never, State>, config?: TestConfig, data?: TestData<Custom>): TestableComponent<State, void, never, Custom>;
|
|
235
|
+
type ExactlyOne = {
|
|
230
236
|
_type: 'ExactlyOne';
|
|
231
237
|
selector: string;
|
|
232
238
|
};
|
|
233
|
-
|
|
239
|
+
type ZeroOrMore = {
|
|
234
240
|
_type: 'ZeroOrMore';
|
|
235
241
|
selector: string;
|
|
236
242
|
};
|
|
237
|
-
|
|
243
|
+
type ZeroOrOne = {
|
|
238
244
|
_type: 'ZeroOrOne';
|
|
239
245
|
selector: string;
|
|
240
246
|
};
|
|
241
|
-
|
|
247
|
+
type OneOrMore = {
|
|
242
248
|
_type: 'OneOrMore';
|
|
243
249
|
selector: string;
|
|
244
250
|
};
|
|
245
251
|
/** Selects elements matching `selector`; throws during `run` if none are found. */
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
252
|
+
declare function one(selector: string): OneOrMore;
|
|
253
|
+
type QuerySelector = ExactlyOne | OneOrMore | ZeroOrMore | ZeroOrOne;
|
|
254
|
+
|
|
255
|
+
export { type AdvanceTime, type AppBadgeOperation, type BroadcastSentRecord, type ClearAppBadge, type Click, type ConfirmInteraction, type DbStoreSnapshot, type DomElement, type DomNode, type DownloadRecord, type ExactlyOne, type FireCustomEvent, HttpError, type HttpHandler, type HttpInteraction, HttpRequest, HttpResponse, type Interaction, InternalLocation, type NonEmptyArray, type OneOrMore, type PromptInteraction, type QuerySelector, type ReceiveBroadcast, RequestError, Result, type SetAppBadge, type Submit, type TestConfig, type TestData, TestDatabaseData, type TestInput, type TestableComponent, type TestableDom, type TextInput, type ZeroOrMore, type ZeroOrOne, advanceTime, appBadgeCount, attr, clearAppBadge, click, defaultTestConfig, fireCustomEvent, newTestData, one, receiveBroadcast, setAppBadge, submit, testApplication, testComponent, textInput };
|