ctrl-fx 0.1.0 → 0.1.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/README.md +13 -0
- package/dist/chunk-DZAR6PTR.js +3966 -0
- package/dist/chunk-KNHJPAIU.js +1800 -0
- package/dist/chunk-NSWOTCDU.js +916 -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-fpCmXVEu.d.ts +1391 -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 +66 -60
- package/dist/testing.js +39 -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-fpCmXVEu.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-DZAR6PTR.js";
|
|
8
|
+
import "./chunk-NSWOTCDU.js";
|
|
9
|
+
import "./chunk-KNHJPAIU.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-fpCmXVEu.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-KNHJPAIU.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,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
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-fpCmXVEu.js';
|
|
2
|
+
import { KeyPath, JsonValue, DbName, ObjectStore } from './db/index.js';
|
|
3
|
+
|
|
4
|
+
type NonEmptyArray<A> = [A, ...A[]];
|
|
5
|
+
|
|
6
|
+
type DbStoreSnapshot = {
|
|
7
|
+
readonly keyPath: KeyPath;
|
|
8
|
+
readonly records: ReadonlyMap<string, JsonValue>;
|
|
9
|
+
readonly autoIncrementCounter: number;
|
|
10
|
+
};
|
|
11
|
+
declare class TestDatabaseData {
|
|
12
|
+
readonly _databases: ReadonlyMap<string, ReadonlyMap<string, DbStoreSnapshot>>;
|
|
13
|
+
constructor(databases: ReadonlyMap<string, ReadonlyMap<string, DbStoreSnapshot>>);
|
|
14
|
+
records(db: DbName, store: ObjectStore): readonly JsonValue[];
|
|
15
|
+
getByKey(db: DbName, store: ObjectStore, key: IDBValidKey): JsonValue | undefined;
|
|
16
|
+
size(db: DbName, store: ObjectStore): number;
|
|
17
|
+
hasDatabase(db: DbName): boolean;
|
|
18
|
+
hasStore(db: DbName, store: ObjectStore): boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type DownloadRecord = {
|
|
17
22
|
readonly filename: string;
|
|
18
23
|
readonly content: string;
|
|
19
24
|
readonly contentType: string;
|
|
20
25
|
};
|
|
21
|
-
|
|
26
|
+
type BroadcastSentRecord = {
|
|
22
27
|
readonly channel: string;
|
|
23
28
|
readonly message: unknown;
|
|
24
29
|
};
|
|
25
|
-
|
|
30
|
+
type SetAppBadge = {
|
|
26
31
|
_type: 'SetAppBadge';
|
|
27
32
|
count: number;
|
|
28
33
|
};
|
|
29
|
-
|
|
34
|
+
type ClearAppBadge = {
|
|
30
35
|
_type: 'ClearAppBadge';
|
|
31
36
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
type AppBadgeOperation = SetAppBadge | ClearAppBadge;
|
|
38
|
+
declare const clearAppBadge: ClearAppBadge;
|
|
39
|
+
declare function setAppBadge(count: number): SetAppBadge;
|
|
40
|
+
declare function appBadgeCount(operations: readonly AppBadgeOperation[]): number;
|
|
41
|
+
type HttpInteraction = {
|
|
37
42
|
readonly request: HttpRequest;
|
|
38
43
|
readonly response: Result<HttpResponse, RequestError | HttpError>;
|
|
39
44
|
};
|
|
40
|
-
|
|
45
|
+
type HttpHandler = (request: HttpRequest, prior: readonly HttpInteraction[]) => Result<HttpResponse, RequestError | HttpError>;
|
|
41
46
|
/** Configuration passed to `testApplication`/`testComponent` to control how side effects behave during tests. */
|
|
42
|
-
|
|
47
|
+
type TestConfig = {
|
|
43
48
|
readonly http: {
|
|
44
49
|
/** Called for each HTTP request. Throw or return a failure Result to simulate errors. */
|
|
45
50
|
readonly handler: HttpHandler;
|
|
@@ -54,18 +59,18 @@ export type TestConfig = {
|
|
|
54
59
|
};
|
|
55
60
|
};
|
|
56
61
|
/** Creates a TestConfig that throws on any HTTP request. */
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
declare function defaultTestConfig(): TestConfig;
|
|
63
|
+
type ConfirmInteraction = {
|
|
59
64
|
message: string;
|
|
60
65
|
response: boolean;
|
|
61
66
|
};
|
|
62
|
-
|
|
67
|
+
type PromptInteraction = {
|
|
63
68
|
message: string;
|
|
64
69
|
default: string | undefined;
|
|
65
70
|
response: string | null;
|
|
66
71
|
};
|
|
67
72
|
/** Snapshot of every observable side effect that occurred during a test run. */
|
|
68
|
-
|
|
73
|
+
type TestData<Custom = {}> = {
|
|
69
74
|
readonly window: {
|
|
70
75
|
readonly alerts: readonly any[];
|
|
71
76
|
readonly confirms: readonly ConfirmInteraction[];
|
|
@@ -119,66 +124,66 @@ export type TestData<Custom = {}> = {
|
|
|
119
124
|
readonly custom: Custom;
|
|
120
125
|
};
|
|
121
126
|
/** Creates an empty TestData, optionally initialising the `custom` field. */
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
declare function newTestData<Custom = {}>(custom?: Custom): TestData<Custom>;
|
|
128
|
+
type TestInput<State, Params, Custom = {}> = {
|
|
124
129
|
state?: State;
|
|
125
130
|
params?: Params;
|
|
126
131
|
testData?: TestData<Custom>;
|
|
127
132
|
};
|
|
128
|
-
|
|
133
|
+
type Click = {
|
|
129
134
|
type: 'Click';
|
|
130
135
|
selector: QuerySelector;
|
|
131
136
|
};
|
|
132
137
|
/** Simulates a click on the element(s) matching `selector`. */
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
declare function click(selector: QuerySelector): Click;
|
|
139
|
+
type AdvanceTime = {
|
|
135
140
|
_type: 'AdvanceTime';
|
|
136
141
|
milliseconds: number;
|
|
137
142
|
};
|
|
138
143
|
/** Advances the test scheduler clock by `milliseconds`, firing any scheduled tasks that come due. */
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
declare function advanceTime(milliseconds: number): AdvanceTime;
|
|
145
|
+
type ReceiveBroadcast = {
|
|
141
146
|
_type: 'ReceiveBroadcast';
|
|
142
147
|
channel: string;
|
|
143
148
|
message: unknown;
|
|
144
149
|
};
|
|
145
150
|
/** Delivers a BroadcastChannel message to any active subscriber on `channel`. */
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
declare function receiveBroadcast(channel: string, message: unknown): ReceiveBroadcast;
|
|
152
|
+
type FireCustomEvent = {
|
|
148
153
|
_type: 'FireCustomEvent';
|
|
149
154
|
selector: QuerySelector;
|
|
150
155
|
eventName: string;
|
|
151
156
|
detail: unknown;
|
|
152
157
|
};
|
|
153
158
|
/** Dispatches a custom DOM event on the element matching `selector`, invoking any `onEvent` handler. */
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
declare function fireCustomEvent(selector: QuerySelector, eventName: string, detail?: unknown): FireCustomEvent;
|
|
160
|
+
type Submit = {
|
|
156
161
|
_type: 'Submit';
|
|
157
162
|
selector: QuerySelector;
|
|
158
163
|
};
|
|
159
164
|
/** Simulates a form submit event on the element(s) matching `selector`. */
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
declare function submit(selector: QuerySelector): Submit;
|
|
166
|
+
type TextInput = {
|
|
162
167
|
_type: 'TextInput';
|
|
163
168
|
selector: QuerySelector;
|
|
164
169
|
value: string;
|
|
165
170
|
};
|
|
166
171
|
/** Simulates an `input` event on the element(s) matching `selector`. */
|
|
167
|
-
|
|
172
|
+
declare function textInput(selector: QuerySelector, value: string): TextInput;
|
|
168
173
|
/** Creates an attribute object `{ name, value }` for use with `findOne(...).attrs.toContainEqual(attr(...))`. */
|
|
169
|
-
|
|
174
|
+
declare function attr(name: string, value: string): {
|
|
170
175
|
name: string;
|
|
171
176
|
value: string;
|
|
172
177
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
178
|
+
type Interaction = Click | AdvanceTime | ReceiveBroadcast | FireCustomEvent | Submit | TextInput;
|
|
179
|
+
|
|
180
|
+
type DomElement = {
|
|
176
181
|
readonly tag: string;
|
|
177
182
|
readonly attrs: readonly Attr[];
|
|
178
183
|
readonly childNodes: readonly DomNode[];
|
|
179
184
|
};
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
type DomNode = DomElement | string;
|
|
186
|
+
type TestableDom = {
|
|
182
187
|
head: DomElement;
|
|
183
188
|
body: DomElement;
|
|
184
189
|
};
|
|
@@ -188,7 +193,7 @@ export type TestableDom = {
|
|
|
188
193
|
* `TestableComponent` reflecting the state after those interactions, so tests
|
|
189
194
|
* can chain calls to build up complex scenarios step by step.
|
|
190
195
|
*/
|
|
191
|
-
|
|
196
|
+
type TestableComponent<State, Params, Event, Custom = {}> = {
|
|
192
197
|
readonly config: TestConfig;
|
|
193
198
|
readonly state: State;
|
|
194
199
|
readonly data: TestData<Custom>;
|
|
@@ -218,31 +223,32 @@ export type TestableComponent<State, Params, Event, Custom = {}> = {
|
|
|
218
223
|
* component that was created with `component()`. For testing a top-level view
|
|
219
224
|
* function directly, use `testApplication` instead.
|
|
220
225
|
*/
|
|
221
|
-
|
|
226
|
+
declare function testComponent<State, Params, Event, Custom = {}>(component: Component<State, Params, Event>, config?: TestConfig, data?: TestData<Custom>): TestableComponent<State, Params, Event, Custom>;
|
|
222
227
|
/**
|
|
223
228
|
* The main entry point for testing a ctrl-fx application. Wraps a view
|
|
224
229
|
* function and initial state into a `TestableComponent`. Call `.run(...)`
|
|
225
230
|
* with interactions to simulate user actions, then inspect `.state`, `.data`,
|
|
226
231
|
* and the `findOne`/`find` DOM query methods on the result.
|
|
227
232
|
*/
|
|
228
|
-
|
|
229
|
-
|
|
233
|
+
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>;
|
|
234
|
+
type ExactlyOne = {
|
|
230
235
|
_type: 'ExactlyOne';
|
|
231
236
|
selector: string;
|
|
232
237
|
};
|
|
233
|
-
|
|
238
|
+
type ZeroOrMore = {
|
|
234
239
|
_type: 'ZeroOrMore';
|
|
235
240
|
selector: string;
|
|
236
241
|
};
|
|
237
|
-
|
|
242
|
+
type ZeroOrOne = {
|
|
238
243
|
_type: 'ZeroOrOne';
|
|
239
244
|
selector: string;
|
|
240
245
|
};
|
|
241
|
-
|
|
246
|
+
type OneOrMore = {
|
|
242
247
|
_type: 'OneOrMore';
|
|
243
248
|
selector: string;
|
|
244
249
|
};
|
|
245
250
|
/** Selects elements matching `selector`; throws during `run` if none are found. */
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
251
|
+
declare function one(selector: string): OneOrMore;
|
|
252
|
+
type QuerySelector = ExactlyOne | OneOrMore | ZeroOrMore | ZeroOrOne;
|
|
253
|
+
|
|
254
|
+
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, 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 };
|