@manyducks.co/dolla 0.69.3 → 0.69.4
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/lib/classes/EventEmitter.d.ts +44 -0
- package/lib/index.js +274 -272
- package/lib/index.js.map +4 -4
- package/lib/nodes/text.d.ts +1 -1
- package/lib/routing.d.ts +79 -0
- package/lib/routing.test.d.ts +1 -0
- package/lib/state.d.ts +1 -1
- package/lib/store.d.ts +1 -1
- package/lib/typeChecking.d.ts +191 -0
- package/lib/types.d.ts +1 -1
- package/package.json +8 -9
- package/tests/state.test.js +52 -52
package/lib/nodes/text.d.ts
CHANGED
package/lib/routing.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type RouteMatch<T = Record<string, any>> = {
|
|
2
|
+
/**
|
|
3
|
+
* The path string that triggered this match.
|
|
4
|
+
*/
|
|
5
|
+
path: string;
|
|
6
|
+
/**
|
|
7
|
+
* The pattern satisfied by `path`.
|
|
8
|
+
*/
|
|
9
|
+
pattern: string;
|
|
10
|
+
/**
|
|
11
|
+
* Named params as parsed from `path`.
|
|
12
|
+
*/
|
|
13
|
+
params: Record<string, string | number>;
|
|
14
|
+
/**
|
|
15
|
+
* Query params as parsed from `path`.
|
|
16
|
+
*/
|
|
17
|
+
query: Record<string, string | number | boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Metadata registered to this route.
|
|
20
|
+
*/
|
|
21
|
+
meta: T;
|
|
22
|
+
};
|
|
23
|
+
export declare enum FragTypes {
|
|
24
|
+
Literal = 1,
|
|
25
|
+
Param = 2,
|
|
26
|
+
Wildcard = 3,
|
|
27
|
+
NumericParam = 4
|
|
28
|
+
}
|
|
29
|
+
export type RouteFragment = {
|
|
30
|
+
name: string;
|
|
31
|
+
type: FragTypes;
|
|
32
|
+
value: string | number | null;
|
|
33
|
+
};
|
|
34
|
+
export type Route<T> = {
|
|
35
|
+
pattern: string;
|
|
36
|
+
fragments: RouteFragment[];
|
|
37
|
+
meta: T;
|
|
38
|
+
};
|
|
39
|
+
export type RouteMatchOptions<T> = {
|
|
40
|
+
willMatch?: (route: Route<T>) => boolean;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Separates a URL path into multiple fragments.
|
|
44
|
+
*
|
|
45
|
+
* @param path - A path string (e.g. `"/api/users/5"`)
|
|
46
|
+
* @returns an array of fragments (e.g. `["api", "users", "5"]`)
|
|
47
|
+
*/
|
|
48
|
+
export declare function splitPath(path: string): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Joins multiple URL path fragments into a single string.
|
|
51
|
+
*
|
|
52
|
+
* @param parts - One or more URL fragments (e.g. `["api", "users", 5]`)
|
|
53
|
+
* @returns a joined path (e.g. `"api/users/5"`)
|
|
54
|
+
*/
|
|
55
|
+
export declare function joinPath(parts: {
|
|
56
|
+
toString(): string;
|
|
57
|
+
}[]): string;
|
|
58
|
+
export declare function resolvePath(base: string, part: string | null): string;
|
|
59
|
+
export declare function parseQueryParams(query: string): Record<string, string | number | boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the nearest match, or undefined if the path matches no route.
|
|
62
|
+
*
|
|
63
|
+
* @param url - Path to match against routes.
|
|
64
|
+
* @param options - Options to customize how matching operates.
|
|
65
|
+
*/
|
|
66
|
+
export declare function matchRoutes<T>(routes: Route<T>[], url: string, options?: RouteMatchOptions<T>): RouteMatch<T> | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Sort routes descending by specificity. Guarantees that the most specific route matches first
|
|
69
|
+
* no matter the order in which they were added.
|
|
70
|
+
*
|
|
71
|
+
* Routes without named params and routes with more fragments are weighted more heavily.
|
|
72
|
+
*/
|
|
73
|
+
export declare function sortRoutes<T>(routes: Route<T>[]): Route<T>[];
|
|
74
|
+
/**
|
|
75
|
+
* Converts a route pattern into a set of matchable fragments.
|
|
76
|
+
*
|
|
77
|
+
* @param route - A route string (e.g. "/api/users/{id}")
|
|
78
|
+
*/
|
|
79
|
+
export declare function patternToFragments(pattern: string): RouteFragment[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/state.d.ts
CHANGED
|
@@ -98,5 +98,5 @@ export declare function observe<I1, I2, I3, I4, I5, I6, I7>(state1: MaybeReadabl
|
|
|
98
98
|
export declare function observe<I1, I2, I3, I4, I5, I6, I7, I8>(state1: MaybeReadable<I1>, state2: MaybeReadable<I2>, state3: MaybeReadable<I3>, state4: MaybeReadable<I4>, state5: MaybeReadable<I5>, state6: MaybeReadable<I6>, state7: MaybeReadable<I7>, state8: MaybeReadable<I8>, callback: (value1: I1, value2: I2, value3: I3, value4: I4, value5: I5, value6: I6, value7: I7, value8: I8) => void): StopFunction;
|
|
99
99
|
export declare function observe<I1, I2, I3, I4, I5, I6, I7, I8, I9>(state1: MaybeReadable<I1>, state2: MaybeReadable<I2>, state3: MaybeReadable<I3>, state4: MaybeReadable<I4>, state5: MaybeReadable<I5>, state6: MaybeReadable<I6>, state7: MaybeReadable<I7>, state8: MaybeReadable<I8>, state9: MaybeReadable<I9>, callback: (value1: I1, value2: I2, value3: I3, value4: I4, value5: I5, value6: I6, value7: I7, value8: I8, value9: I9) => void): StopFunction;
|
|
100
100
|
export declare function observe<I1, I2, I3, I4, I5, I6, I7, I8, I9, I10>(state1: MaybeReadable<I1>, state2: MaybeReadable<I2>, state3: MaybeReadable<I3>, state4: MaybeReadable<I4>, state5: MaybeReadable<I5>, state6: MaybeReadable<I6>, state7: MaybeReadable<I7>, state8: MaybeReadable<I8>, state9: MaybeReadable<I9>, state10: MaybeReadable<I10>, callback: (value1: I1, value2: I2, value3: I3, value4: I4, value5: I5, value6: I6, value7: I7, value8: I8, value9: I9, value10: I10) => void): StopFunction;
|
|
101
|
-
export declare function unwrap<T>(value:
|
|
101
|
+
export declare function unwrap<T>(value: MaybeReadable<T>): T;
|
|
102
102
|
export {};
|
package/lib/store.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AppContext, type ElementContext } from "./app.js";
|
|
2
2
|
import { type DebugChannel } from "./classes/DebugHub.js";
|
|
3
|
-
import { MaybeReadable, type ReadableValues } from "./state.js";
|
|
3
|
+
import { type MaybeReadable, type ReadableValues } from "./state.js";
|
|
4
4
|
import type { BuiltInStores } from "./types.js";
|
|
5
5
|
export type Store<O, E> = (context: StoreContext<O>) => E | Promise<E>;
|
|
6
6
|
export interface StoreContext<Options = any> extends DebugChannel {
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
type TypeNames = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null" | "array" | "class" | "promise" | "NaN";
|
|
2
|
+
/**
|
|
3
|
+
* Extends `typeof` operator with more specific and useful type distinctions.
|
|
4
|
+
*/
|
|
5
|
+
export declare function typeOf(value: unknown): TypeNames;
|
|
6
|
+
/**
|
|
7
|
+
* Throws a TypeError unless `condition` is truthy.
|
|
8
|
+
*
|
|
9
|
+
* @param condition - Value whose truthiness is in question.
|
|
10
|
+
* @param errorMessage - Optional message for the thrown TypeError.
|
|
11
|
+
*/
|
|
12
|
+
export declare function assert(condition: any, errorMessage?: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Returns true if `value` is an array.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isArray(value: unknown): value is Array<unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Throws an error if `value` is not an array.
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertArray(value: unknown, errorMessage?: string): value is Array<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns a function that takes a `value` and ensures that it is an array for which `check` returns true for every item.
|
|
23
|
+
*
|
|
24
|
+
* @param check - Function to check items against.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];
|
|
27
|
+
/**
|
|
28
|
+
* Returns true when `value` is an array and `check` returns true for every item.
|
|
29
|
+
*
|
|
30
|
+
* @param check - Function to check items against.
|
|
31
|
+
* @param value - A possible array.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isArrayOf<T>(check: (item: unknown) => boolean, value: unknown): value is T[];
|
|
34
|
+
/**
|
|
35
|
+
* Returns a function that takes a `value` and throws a TypeError unless it is an array for which `check` returns true for every item.
|
|
36
|
+
*
|
|
37
|
+
* @param check - Function to check items against.
|
|
38
|
+
*/
|
|
39
|
+
export declare function assertArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];
|
|
40
|
+
/**
|
|
41
|
+
* Throws a TypeError unless `value` is an array and `check` returns true for every item.
|
|
42
|
+
*
|
|
43
|
+
* @param check - Function to check items against.
|
|
44
|
+
* @param value - A possible array.
|
|
45
|
+
* @param errorMessage - A custom error message.
|
|
46
|
+
*/
|
|
47
|
+
export declare function assertArrayOf<T>(check: (item: unknown) => boolean, value: unknown, errorMessage?: string): value is T[];
|
|
48
|
+
/**
|
|
49
|
+
* Returns true if `value` is equal to `true` or `false`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isBoolean(value: unknown): value is boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Throws a TypeError unless `value` is equal to `true` or `false`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function assertBoolean(value: unknown, errorMessage?: string): value is boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Returns true if `value` is a string.
|
|
58
|
+
*/
|
|
59
|
+
export declare function isString(value: unknown): value is string;
|
|
60
|
+
/**
|
|
61
|
+
* Throws a TypeError unless `value` is a string.
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertString(value: unknown, errorMessage?: string): value is string;
|
|
64
|
+
/**
|
|
65
|
+
* Returns true if `value` is a function (but not a class).
|
|
66
|
+
*/
|
|
67
|
+
export declare function isFunction<T = (...args: unknown[]) => unknown>(value: unknown): value is T;
|
|
68
|
+
/**
|
|
69
|
+
* Throws a TypeError unless `value` is a function.
|
|
70
|
+
*/
|
|
71
|
+
export declare function assertFunction<T = (...args: unknown[]) => unknown>(value: unknown, errorMessage?: string): value is T;
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if `value` is a number.
|
|
74
|
+
*/
|
|
75
|
+
export declare function isNumber(value: unknown): value is number;
|
|
76
|
+
/**
|
|
77
|
+
* Throws a TypeError unless `value` is a number.
|
|
78
|
+
*/
|
|
79
|
+
export declare function assertNumber(value: unknown, errorMessage?: string): value is number;
|
|
80
|
+
/**
|
|
81
|
+
* Returns true if `value` implements the Promise protocol.
|
|
82
|
+
* This matches true instances of Promise as well as any object that
|
|
83
|
+
* implements `next`, `catch` and `finally` methods.
|
|
84
|
+
*
|
|
85
|
+
* To strictly match instances of Promise, use `isInstanceOf(Promise)`.
|
|
86
|
+
*/
|
|
87
|
+
export declare function isPromise<T = unknown>(value: unknown): value is Promise<T>;
|
|
88
|
+
/**
|
|
89
|
+
* Throws a TypeError unless `value` implements the Promise protocol.
|
|
90
|
+
* This matches true instances of Promise as well as any object that
|
|
91
|
+
* implements `next`, `catch` and `finally` methods.
|
|
92
|
+
*
|
|
93
|
+
* To strictly allow only instances of Promise, use `Type.assertInstanceOf(Promise)`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function assertPromise<T = unknown>(value: unknown, errorMessage?: string): value is Promise<T>;
|
|
96
|
+
/**
|
|
97
|
+
* Returns true if `value` is a class.
|
|
98
|
+
*/
|
|
99
|
+
export declare function isClass(value: unknown): value is {
|
|
100
|
+
new (): unknown;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Throws a TypeError unless `value` is a class.
|
|
104
|
+
*/
|
|
105
|
+
export declare function assertClass(value: unknown, errorMessage?: string): value is {
|
|
106
|
+
new (): unknown;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Returns a function that takes a `value` and returns true if `value` is an instance of `constructor`.
|
|
110
|
+
*
|
|
111
|
+
* @param constructor - The constructor a value must be an instance of to match.
|
|
112
|
+
*/
|
|
113
|
+
export declare function isInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;
|
|
114
|
+
/**
|
|
115
|
+
* Returns `true` if `value` is an instance of `constructor`.
|
|
116
|
+
*
|
|
117
|
+
* @param constructor - The constructor `value` must be an instance of.
|
|
118
|
+
* @param value - A value that may be an instance of `constructor`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function isInstanceOf<T extends Function>(constructor: T, value: unknown): value is T;
|
|
121
|
+
/**
|
|
122
|
+
* Returns a function that takes a `value` and throws a TypeError unless `value` is an instance of `constructor`.
|
|
123
|
+
*
|
|
124
|
+
* @param constructor - The constructor a value must be an instance of to match.
|
|
125
|
+
*/
|
|
126
|
+
export declare function assertInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;
|
|
127
|
+
/**
|
|
128
|
+
* Throws a TypeError unless `value` is an instance of `constructor`.
|
|
129
|
+
*
|
|
130
|
+
* @param constructor - The constructor `value` must be an instance of.
|
|
131
|
+
* @param value - A value that may be an instance of `constructor`.
|
|
132
|
+
* @param errorMessage - A custom error message for when the assertion fails.
|
|
133
|
+
*/
|
|
134
|
+
export declare function assertInstanceOf<T extends Function>(constructor: T, value: unknown, errorMessage?: string): value is T;
|
|
135
|
+
/**
|
|
136
|
+
* Returns true if `value` is a Map.
|
|
137
|
+
*/
|
|
138
|
+
export declare function isMap<K = unknown, V = unknown>(value: any): value is Map<K, V>;
|
|
139
|
+
/**
|
|
140
|
+
* Throws a TypeError unless `value` is a Map.
|
|
141
|
+
*/
|
|
142
|
+
export declare function assertMap<K = unknown, V = unknown>(value: any, errorMessage?: string): value is Map<K, V>;
|
|
143
|
+
/**
|
|
144
|
+
* Returns true if `value` is a Set.
|
|
145
|
+
*/
|
|
146
|
+
export declare function isSet<T = unknown>(value: any): value is Set<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Throws a TypeError if `value` is not a Set.
|
|
149
|
+
*/
|
|
150
|
+
export declare function assertSet<T = unknown>(value: any, errorMessage?: string): value is Set<T>;
|
|
151
|
+
/**
|
|
152
|
+
* Returns true if `value` implements the Iterable protocol.
|
|
153
|
+
*/
|
|
154
|
+
export declare function isIterable<T>(value: any): value is Iterable<T>;
|
|
155
|
+
/**
|
|
156
|
+
* Throws a TypeError unless `value` implements the Iterable protocol.
|
|
157
|
+
*/
|
|
158
|
+
export declare function assertIterable<T>(value: any, errorMessage?: string): value is Iterable<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Returns true if `value` is a plain JavaScript object.
|
|
161
|
+
*/
|
|
162
|
+
export declare function isObject(value: unknown): value is Record<string | number | symbol, unknown>;
|
|
163
|
+
/**
|
|
164
|
+
* Throws a TypeError unless `value` is a plain JavaScript object.
|
|
165
|
+
*/
|
|
166
|
+
export declare function assertObject(value: unknown, errorMessage?: string): value is object;
|
|
167
|
+
/**
|
|
168
|
+
* Returns true if `value` is equal to `null`.
|
|
169
|
+
*/
|
|
170
|
+
export declare function isNull(value: unknown): value is null;
|
|
171
|
+
/**
|
|
172
|
+
* Throws a TypeError unless `value` is equal to `null`.
|
|
173
|
+
*/
|
|
174
|
+
export declare function assertNull(value: unknown, errorMessage?: string): value is null;
|
|
175
|
+
/**
|
|
176
|
+
* Returns true if `value` is equal to `undefined`.
|
|
177
|
+
*/
|
|
178
|
+
export declare function isUndefined(value: unknown): value is undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Throws a TypeError unless `value` is equal to `undefined`.
|
|
181
|
+
*/
|
|
182
|
+
export declare function assertUndefined(value: unknown, errorMessage?: string): value is undefined;
|
|
183
|
+
/**
|
|
184
|
+
* Returns true if `value` is equal to `null` or `undefined`.
|
|
185
|
+
*/
|
|
186
|
+
export declare function isEmpty(value: unknown): value is void;
|
|
187
|
+
/**
|
|
188
|
+
* Throws a TypeError unless `value` is equal to `null` or `undefined`.
|
|
189
|
+
*/
|
|
190
|
+
export declare function assertEmpty(value: unknown, errorMessage?: string): value is void;
|
|
191
|
+
export {};
|
package/lib/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type Markup } from "./markup.js";
|
|
|
3
3
|
import { type Readable, type Writable } from "./state.js";
|
|
4
4
|
import { type Store } from "./store.js";
|
|
5
5
|
import { type DocumentStore } from "./stores/document.js";
|
|
6
|
-
import { RenderStore } from "./stores/render.js";
|
|
6
|
+
import { type RenderStore } from "./stores/render.js";
|
|
7
7
|
/**
|
|
8
8
|
* Value will be read by the component.
|
|
9
9
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manyducks.co/dolla",
|
|
3
|
-
"version": "0.69.
|
|
3
|
+
"version": "0.69.4",
|
|
4
4
|
"description": "Front-end components, routing and state management.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"repository": "https://github.com/manyducksco/dolla",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "
|
|
11
|
+
"test": "npm run build && node --test",
|
|
12
12
|
"build": "tsc && node build.js",
|
|
13
13
|
"start": "tsc --watch",
|
|
14
14
|
"prepublishOnly": "NODE_ENV=production npm run build"
|
|
@@ -39,18 +39,17 @@
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@borf/bedrock": "^3.1.0",
|
|
43
42
|
"fetch-ponyfill": "^7.1.0",
|
|
44
43
|
"history": "^5.3.0",
|
|
45
|
-
"nanoid": "^
|
|
44
|
+
"nanoid": "^5.0.4",
|
|
46
45
|
"simple-color-hash": "^1.0.2"
|
|
47
46
|
},
|
|
48
47
|
"devDependencies": {
|
|
49
48
|
"@types/node": "^18.17.6",
|
|
50
|
-
"csstype": "^3.1.
|
|
51
|
-
"esbuild": "^0.
|
|
52
|
-
"prettier": "^2.
|
|
53
|
-
"typescript": "^5.
|
|
54
|
-
"zod": "^3.22.
|
|
49
|
+
"csstype": "^3.1.3",
|
|
50
|
+
"esbuild": "^0.20.0",
|
|
51
|
+
"prettier": "^3.2.4",
|
|
52
|
+
"typescript": "^5.3.3",
|
|
53
|
+
"zod": "^3.22.4"
|
|
55
54
|
}
|
|
56
55
|
}
|
package/tests/state.test.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert";
|
|
3
|
-
import {
|
|
3
|
+
import { $, $$, observe, unwrap, isReadable, isWritable } from "../lib/index.js";
|
|
4
4
|
|
|
5
5
|
test("isReadable, isWritable: returns correct results", (t) => {
|
|
6
|
-
const $$writable =
|
|
7
|
-
const $readable =
|
|
8
|
-
const $computed =
|
|
6
|
+
const $$writable = $$(5);
|
|
7
|
+
const $readable = $($$writable);
|
|
8
|
+
const $computed = $($readable, (x) => x * 2);
|
|
9
9
|
|
|
10
10
|
assert.strictEqual(isWritable($$writable), true);
|
|
11
11
|
assert.strictEqual(isReadable($$writable), true);
|
|
@@ -18,16 +18,16 @@ test("isReadable, isWritable: returns correct results", (t) => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
test("readable, writable, computed: basic functionality", (t) => {
|
|
21
|
-
const $$writable =
|
|
22
|
-
const $readable =
|
|
23
|
-
const $x =
|
|
24
|
-
const $y =
|
|
21
|
+
const $$writable = $$("writable");
|
|
22
|
+
const $readable = $("test");
|
|
23
|
+
const $x = $($readable, (v) => v.toUpperCase());
|
|
24
|
+
const $y = $($$writable);
|
|
25
25
|
|
|
26
|
-
const compute = t.mock.fn((
|
|
26
|
+
const compute = t.mock.fn((x, y) => {
|
|
27
27
|
return x + y;
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
const $computed =
|
|
30
|
+
const $computed = $([$x, $y], compute);
|
|
31
31
|
|
|
32
32
|
assert.strictEqual($computed.get(), "TESTwritable");
|
|
33
33
|
|
|
@@ -51,15 +51,15 @@ test("readable, writable, computed: basic functionality", (t) => {
|
|
|
51
51
|
assert.strictEqual($computed.get(), "TESTcan you hear me now?");
|
|
52
52
|
|
|
53
53
|
assert.strictEqual(observer.mock.calls.length, 3);
|
|
54
|
-
assert.deepEqual(observer.mock.calls[0].arguments, ["writable"
|
|
55
|
-
assert.deepEqual(observer.mock.calls[1].arguments, ["new value"
|
|
56
|
-
assert.deepEqual(observer.mock.calls[2].arguments, ["new value 2"
|
|
54
|
+
assert.deepEqual(observer.mock.calls[0].arguments, ["writable"]);
|
|
55
|
+
assert.deepEqual(observer.mock.calls[1].arguments, ["new value"]);
|
|
56
|
+
assert.deepEqual(observer.mock.calls[2].arguments, ["new value 2"]);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
test("writable -> readable -> readable: chained transforms", (t) => {
|
|
60
|
-
const $$number =
|
|
61
|
-
const $doubled =
|
|
62
|
-
const $quadrupled =
|
|
60
|
+
const $$number = $$(5);
|
|
61
|
+
const $doubled = $($$number, (x) => x * 2);
|
|
62
|
+
const $quadrupled = $($doubled, (x) => x * 2);
|
|
63
63
|
const observer = t.mock.fn();
|
|
64
64
|
|
|
65
65
|
assert.strictEqual($doubled.get(), 10);
|
|
@@ -68,12 +68,12 @@ test("writable -> readable -> readable: chained transforms", (t) => {
|
|
|
68
68
|
const stop = observe($quadrupled, observer);
|
|
69
69
|
|
|
70
70
|
assert.strictEqual(observer.mock.calls.length, 1);
|
|
71
|
-
assert.deepEqual(observer.mock.calls[0].arguments, [20
|
|
71
|
+
assert.deepEqual(observer.mock.calls[0].arguments, [20]);
|
|
72
72
|
|
|
73
73
|
$$number.set(50);
|
|
74
74
|
|
|
75
75
|
assert.strictEqual(observer.mock.calls.length, 2);
|
|
76
|
-
assert.deepEqual(observer.mock.calls[1].arguments, [200
|
|
76
|
+
assert.deepEqual(observer.mock.calls[1].arguments, [200]);
|
|
77
77
|
|
|
78
78
|
stop();
|
|
79
79
|
|
|
@@ -86,7 +86,7 @@ test("writable -> readable -> readable: chained transforms", (t) => {
|
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
test("writable: update", (t) => {
|
|
89
|
-
const $$numbers =
|
|
89
|
+
const $$numbers = $$(["one", "two", "three"]);
|
|
90
90
|
|
|
91
91
|
const original = $$numbers.get();
|
|
92
92
|
|
|
@@ -99,54 +99,54 @@ test("writable: update", (t) => {
|
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
test("readable, writable, computed: observer called with initial value when registered", (t) => {
|
|
102
|
-
const $$value =
|
|
103
|
-
const $value =
|
|
104
|
-
const $doubled =
|
|
105
|
-
const $multi =
|
|
102
|
+
const $$value = $$(1);
|
|
103
|
+
const $value = $(5);
|
|
104
|
+
const $doubled = $($value, (x) => x * 2);
|
|
105
|
+
const $multi = $([$value, $doubled], (x, y) => x + y);
|
|
106
106
|
|
|
107
107
|
// Writable
|
|
108
108
|
const wObserver = t.mock.fn();
|
|
109
109
|
const wStop = observe($$value, wObserver);
|
|
110
110
|
assert.strictEqual(wObserver.mock.calls.length, 1);
|
|
111
|
-
assert.deepEqual(wObserver.mock.calls[0].arguments, [1
|
|
111
|
+
assert.deepEqual(wObserver.mock.calls[0].arguments, [1]);
|
|
112
112
|
wStop();
|
|
113
113
|
|
|
114
114
|
// Readable
|
|
115
115
|
const rObserver = t.mock.fn();
|
|
116
116
|
const rStop = observe($value, rObserver);
|
|
117
117
|
assert.strictEqual(rObserver.mock.calls.length, 1);
|
|
118
|
-
assert.deepEqual(rObserver.mock.calls[0].arguments, [5
|
|
118
|
+
assert.deepEqual(rObserver.mock.calls[0].arguments, [5]);
|
|
119
119
|
rStop();
|
|
120
120
|
|
|
121
121
|
// Computed (single source)
|
|
122
122
|
const cObserver1 = t.mock.fn();
|
|
123
123
|
const cStop1 = observe($doubled, cObserver1);
|
|
124
124
|
assert.strictEqual(cObserver1.mock.calls.length, 1);
|
|
125
|
-
assert.deepEqual(cObserver1.mock.calls[0].arguments, [10
|
|
125
|
+
assert.deepEqual(cObserver1.mock.calls[0].arguments, [10]);
|
|
126
126
|
cStop1();
|
|
127
127
|
|
|
128
128
|
// Computed (multi source)
|
|
129
129
|
const cObserver2 = t.mock.fn();
|
|
130
130
|
const cStop2 = observe($multi, cObserver2);
|
|
131
131
|
assert.strictEqual(cObserver2.mock.calls.length, 1);
|
|
132
|
-
assert.deepEqual(cObserver2.mock.calls[0].arguments, [15
|
|
132
|
+
assert.deepEqual(cObserver2.mock.calls[0].arguments, [15]);
|
|
133
133
|
cStop2();
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
test("computed: basic functionality", (t) => {
|
|
137
|
-
const $$one =
|
|
138
|
-
const $$two =
|
|
139
|
-
const $$three =
|
|
137
|
+
const $$one = $$(2);
|
|
138
|
+
const $$two = $$(4);
|
|
139
|
+
const $$three = $$(8);
|
|
140
140
|
|
|
141
|
-
const joinFirst = t.mock.fn((
|
|
141
|
+
const joinFirst = t.mock.fn((one, two) => {
|
|
142
142
|
return one + two;
|
|
143
143
|
});
|
|
144
|
-
const $first =
|
|
144
|
+
const $first = $([$$one, $$two], joinFirst);
|
|
145
145
|
|
|
146
|
-
const joinSecond = t.mock.fn((
|
|
146
|
+
const joinSecond = t.mock.fn((one, two, three) => {
|
|
147
147
|
return one + two + three;
|
|
148
148
|
});
|
|
149
|
-
const $second =
|
|
149
|
+
const $second = $([$$one, $$two, $$three], joinSecond);
|
|
150
150
|
|
|
151
151
|
assert.strictEqual($first.get(), 6);
|
|
152
152
|
assert.strictEqual($second.get(), 14);
|
|
@@ -158,7 +158,7 @@ test("computed: basic functionality", (t) => {
|
|
|
158
158
|
const stop = observe($second, observer);
|
|
159
159
|
|
|
160
160
|
assert.strictEqual(observer.mock.callCount(), 1);
|
|
161
|
-
assert.deepEqual(observer.mock.calls[0].arguments, [14
|
|
161
|
+
assert.deepEqual(observer.mock.calls[0].arguments, [14]); // Observer receives initial value.
|
|
162
162
|
assert.strictEqual(joinSecond.mock.callCount(), 2);
|
|
163
163
|
|
|
164
164
|
$$two.set(16);
|
|
@@ -173,7 +173,7 @@ test("computed: basic functionality", (t) => {
|
|
|
173
173
|
assert.strictEqual(joinSecond.mock.callCount(), 3);
|
|
174
174
|
|
|
175
175
|
assert.strictEqual(observer.mock.callCount(), 2); // Observer received value.
|
|
176
|
-
assert.deepEqual(observer.mock.calls[1].arguments, [26
|
|
176
|
+
assert.deepEqual(observer.mock.calls[1].arguments, [26]);
|
|
177
177
|
|
|
178
178
|
stop();
|
|
179
179
|
|
|
@@ -189,10 +189,10 @@ test("computed: basic functionality", (t) => {
|
|
|
189
189
|
});
|
|
190
190
|
|
|
191
191
|
test("computed: observers received value when undefined", (t) => {
|
|
192
|
-
const $$one =
|
|
193
|
-
const $$two =
|
|
192
|
+
const $$one = $$(true);
|
|
193
|
+
const $$two = $$(false);
|
|
194
194
|
|
|
195
|
-
const $joined =
|
|
195
|
+
const $joined = $([$$one, $$two], (one, two) => {
|
|
196
196
|
if (one && two) {
|
|
197
197
|
return true;
|
|
198
198
|
}
|
|
@@ -207,19 +207,19 @@ test("computed: observers received value when undefined", (t) => {
|
|
|
207
207
|
const stop = observe($joined, observer);
|
|
208
208
|
|
|
209
209
|
assert.strictEqual(observer.mock.calls.length, 1);
|
|
210
|
-
assert.deepEqual(observer.mock.calls[0].arguments, [undefined
|
|
210
|
+
assert.deepEqual(observer.mock.calls[0].arguments, [undefined]);
|
|
211
211
|
|
|
212
212
|
$$two.set(true);
|
|
213
213
|
|
|
214
214
|
assert.strictEqual($joined.get(), true);
|
|
215
215
|
assert.strictEqual(observer.mock.calls.length, 2);
|
|
216
|
-
assert.deepEqual(observer.mock.calls[1].arguments, [true
|
|
216
|
+
assert.deepEqual(observer.mock.calls[1].arguments, [true]);
|
|
217
217
|
|
|
218
218
|
$$one.set(false);
|
|
219
219
|
|
|
220
220
|
assert.strictEqual($joined.get(), undefined);
|
|
221
221
|
assert.strictEqual(observer.mock.calls.length, 3);
|
|
222
|
-
assert.deepEqual(observer.mock.calls[2].arguments, [undefined
|
|
222
|
+
assert.deepEqual(observer.mock.calls[2].arguments, [undefined]);
|
|
223
223
|
|
|
224
224
|
stop();
|
|
225
225
|
|
|
@@ -231,14 +231,14 @@ test("computed: observers received value when undefined", (t) => {
|
|
|
231
231
|
});
|
|
232
232
|
|
|
233
233
|
test("computed: observer only gets new values when they are different", (t) => {
|
|
234
|
-
const $$source =
|
|
235
|
-
const $age =
|
|
234
|
+
const $$source = $$({ name: "Jimbo Jones", age: 346 });
|
|
235
|
+
const $age = $($$source, (x) => x.age);
|
|
236
236
|
|
|
237
237
|
const ageObserver = t.mock.fn();
|
|
238
238
|
const stop = observe($age, ageObserver);
|
|
239
239
|
|
|
240
240
|
assert.strictEqual(ageObserver.mock.calls.length, 1);
|
|
241
|
-
assert.deepEqual(ageObserver.mock.calls[0].arguments, [346
|
|
241
|
+
assert.deepEqual(ageObserver.mock.calls[0].arguments, [346]);
|
|
242
242
|
|
|
243
243
|
$$source.update((current) => {
|
|
244
244
|
return { ...current, name: "Not Jimbo Jones" };
|
|
@@ -251,19 +251,19 @@ test("computed: observer only gets new values when they are different", (t) => {
|
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
assert.strictEqual(ageObserver.mock.calls.length, 2); // Age change should have been observed.
|
|
254
|
-
assert.deepEqual(ageObserver.mock.calls[1].arguments, [347
|
|
254
|
+
assert.deepEqual(ageObserver.mock.calls[1].arguments, [347]);
|
|
255
255
|
|
|
256
256
|
stop();
|
|
257
257
|
});
|
|
258
258
|
|
|
259
259
|
test("proxy", (t) => {
|
|
260
|
-
const $$numbers =
|
|
261
|
-
const $$hasTwo =
|
|
262
|
-
get(
|
|
263
|
-
return
|
|
260
|
+
const $$numbers = $$([1, 2, 3]);
|
|
261
|
+
const $$hasTwo = $$($$numbers, {
|
|
262
|
+
get() {
|
|
263
|
+
return $$numbers.get().includes(2);
|
|
264
264
|
},
|
|
265
|
-
set(
|
|
266
|
-
|
|
265
|
+
set(value) {
|
|
266
|
+
$$numbers.update((numbers) => {
|
|
267
267
|
if (value && !numbers.includes(2)) {
|
|
268
268
|
return [...numbers, 2].sort();
|
|
269
269
|
}
|