@manyducks.co/dolla 2.0.0-alpha.34 → 2.0.0-alpha.36
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 +9 -22
- package/dist/core/{batch.d.ts → _batch.d.ts} +4 -0
- package/dist/core/_signals_new.d.ts +130 -0
- package/dist/core/context.d.ts +7 -55
- package/dist/core/dolla.d.ts +7 -48
- package/dist/core/markup.d.ts +9 -31
- package/dist/core/nodes/{observer.d.ts → dynamic.d.ts} +10 -12
- package/dist/core/nodes/html.d.ts +11 -17
- package/dist/core/nodes/list.d.ts +28 -0
- package/dist/core/nodes/outlet.d.ts +7 -7
- package/dist/core/nodes/portal.d.ts +2 -2
- package/dist/core/nodes/view.d.ts +21 -34
- package/dist/core/ref.d.ts +5 -6
- package/dist/core/signals.d.ts +128 -0
- package/dist/core/store.d.ts +14 -18
- package/dist/core/symbols.d.ts +0 -3
- package/dist/{views → core/views}/default-crash-view.d.ts +1 -1
- package/dist/{views → core/views}/passthrough.d.ts +2 -2
- package/dist/{modules/http.d.ts → http/index.d.ts} +1 -2
- package/dist/index.d.ts +8 -11
- package/dist/index.js +517 -695
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/jsx-dev-runtime.js +2 -2
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +2 -2
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/markup-ILMFXzoo.js +1442 -0
- package/dist/markup-ILMFXzoo.js.map +1 -0
- package/dist/{modules/router.d.ts → router/index.d.ts} +5 -5
- package/dist/router/router.utils.test.d.ts +1 -0
- package/dist/{modules/i18n.d.ts → translate/index.d.ts} +20 -16
- package/dist/typeChecking.d.ts +0 -96
- package/dist/types.d.ts +9 -9
- package/dist/utils.d.ts +4 -1
- package/docs/signals.md +149 -0
- package/docs/views.md +1 -87
- package/notes/atomic.md +146 -0
- package/notes/context-routes.md +56 -0
- package/notes/elimination.md +33 -0
- package/package.json +9 -7
- package/vite.config.js +3 -0
- package/dist/core/nodes/repeat.d.ts +0 -36
- package/dist/core/state.d.ts +0 -126
- package/dist/core/stats.d.ts +0 -31
- package/dist/markup-B3FV_fq9.js +0 -1525
- package/dist/markup-B3FV_fq9.js.map +0 -1
- package/notes/viewstate.md +0 -15
- package/tests/state.test.js +0 -135
- /package/dist/{modules/router.utils.test.d.ts → core/signals.test.d.ts} +0 -0
- /package/dist/{modules → router}/router.utils.d.ts +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# What can we remove?
|
|
2
|
+
|
|
3
|
+
I still want to get this library with all its features down below 15kb. It's currently at 17.8kb. That said, I don't want to strip out things that are actually useful. The mission of this library is to be batteries-included, which implies some extra weight.
|
|
4
|
+
|
|
5
|
+
What can be removed without compromising the basics?
|
|
6
|
+
|
|
7
|
+
## Events?
|
|
8
|
+
|
|
9
|
+
> 1st ELIMINATED. We're at 16.77kb now.
|
|
10
|
+
|
|
11
|
+
If we have the ability to get contexts and call methods on them, isn't that just a better version of events?
|
|
12
|
+
|
|
13
|
+
## Logger / Built-in Crash View
|
|
14
|
+
|
|
15
|
+
> REDUCED! Removed simple-color-hash in favor of custom OKLCH hash and we're down to 15.9kb.
|
|
16
|
+
|
|
17
|
+
Logger could be a different package. Crashes could be handled by a crash handler you attach.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
Dolla.onCrash((error) => {
|
|
21
|
+
// Do what you will with this error.
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## HTTP Client?
|
|
26
|
+
|
|
27
|
+
Do we really need this? It's kind of a nice wrapper but the only thing I use the middleware for is to add auth headers for API calls, and it's trivial to write a function around `fetch` that does that. No need for the complexity of middleware.
|
|
28
|
+
|
|
29
|
+
Not really. Fetch is hella basic. I just tried to write my own trivial wrapper around fetch and it took a little too much thought. I don't want to do that for every project. Adding middleware to authenticate feels trivial with `http`.
|
|
30
|
+
|
|
31
|
+
## Markup?
|
|
32
|
+
|
|
33
|
+
Can JSX and `html` return DOM nodes directly? Not really, because views need to be mounted and unmounted like DOM nodes but they don't have the same API. Although I could define a minimal DOM-compatible API so that DOM nodes could directly work.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manyducks.co/dolla",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.36",
|
|
4
4
|
"description": "Front-end components, routing and state management.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "git+https://github.com/manyducksco/dolla.git"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "
|
|
14
|
+
"test": "vitest",
|
|
15
15
|
"build:esbuild": "tsc && node build.js",
|
|
16
16
|
"build": "vite build && tsc",
|
|
17
17
|
"start": "tsc --watch",
|
|
@@ -39,15 +39,17 @@
|
|
|
39
39
|
"types": "./jsx-dev-runtime.d.ts"
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"alien-signals": "^1.0.3",
|
|
44
|
+
"fast-deep-equal": "^3.1.3",
|
|
45
|
+
"htm": "^3.1.1"
|
|
46
|
+
},
|
|
42
47
|
"devDependencies": {
|
|
43
|
-
"@manyducks.co/emitter": "^1.1.2",
|
|
44
48
|
"@types/node": "^22.12.0",
|
|
45
49
|
"csstype": "^3.1.3",
|
|
46
|
-
"fast-deep-equal": "^3.1.3",
|
|
47
|
-
"htm": "^3.1.1",
|
|
48
50
|
"prettier": "^3.4.2",
|
|
49
|
-
"simple-color-hash": "^1.0.2",
|
|
50
51
|
"typescript": "^5.7.3",
|
|
51
|
-
"vite": "^6.0.11"
|
|
52
|
+
"vite": "^6.0.11",
|
|
53
|
+
"vitest": "^3.0.5"
|
|
52
54
|
}
|
|
53
55
|
}
|
package/vite.config.js
CHANGED
|
@@ -8,6 +8,9 @@ export default defineConfig({
|
|
|
8
8
|
lib: {
|
|
9
9
|
entry: {
|
|
10
10
|
index: resolve(__dirname, "src/index.ts"),
|
|
11
|
+
// http: resolve(__dirname, "src/http/index.ts"),
|
|
12
|
+
// router: resolve(__dirname, "src/router/index.ts"),
|
|
13
|
+
// translate: resolve(__dirname, "src/translate/index.ts"),
|
|
11
14
|
"jsx-runtime": resolve(__dirname, "src/jsx-runtime.js"),
|
|
12
15
|
"jsx-dev-runtime": resolve(__dirname, "src/jsx-dev-runtime.js"),
|
|
13
16
|
},
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { type ElementContext } from "../context.js";
|
|
2
|
-
import { type MarkupElement } from "../markup.js";
|
|
3
|
-
import { type Setter, type State, type StopFunction } from "../state.js";
|
|
4
|
-
import { IS_MARKUP_ELEMENT } from "../symbols.js";
|
|
5
|
-
import { type ViewContext, type ViewResult } from "./view.js";
|
|
6
|
-
interface RepeatOptions<T> {
|
|
7
|
-
elementContext: ElementContext;
|
|
8
|
-
$items: State<T[]>;
|
|
9
|
-
keyFn: (value: T, index: number) => string | number | symbol;
|
|
10
|
-
renderFn: ($value: State<T>, $index: State<number>, ctx: ViewContext) => ViewResult;
|
|
11
|
-
}
|
|
12
|
-
type ConnectedItem<T> = {
|
|
13
|
-
key: any;
|
|
14
|
-
$value: State<T>;
|
|
15
|
-
setValue: Setter<T>;
|
|
16
|
-
$index: State<number>;
|
|
17
|
-
setIndex: Setter<number>;
|
|
18
|
-
element: MarkupElement;
|
|
19
|
-
};
|
|
20
|
-
export declare class Repeat<T> implements MarkupElement {
|
|
21
|
-
[IS_MARKUP_ELEMENT]: boolean;
|
|
22
|
-
node: Text;
|
|
23
|
-
$items: State<T[]>;
|
|
24
|
-
stopCallback?: StopFunction;
|
|
25
|
-
connectedItems: ConnectedItem<T>[];
|
|
26
|
-
elementContext: ElementContext;
|
|
27
|
-
renderFn: (this: ViewContext, $value: State<T>, $index: State<number>, context: ViewContext) => ViewResult;
|
|
28
|
-
keyFn: (value: T, index: number) => string | number | symbol;
|
|
29
|
-
get isMounted(): boolean;
|
|
30
|
-
constructor({ elementContext, $items, renderFn, keyFn }: RepeatOptions<T>);
|
|
31
|
-
mount(parent: Node, after?: Node): void;
|
|
32
|
-
unmount(parentIsUnmounting?: boolean): void;
|
|
33
|
-
_cleanup(parentIsUnmounting: boolean): void;
|
|
34
|
-
_update(value: T[]): void;
|
|
35
|
-
}
|
|
36
|
-
export {};
|
package/dist/core/state.d.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { strictEqual } from "../utils";
|
|
2
|
-
import { IS_STATE } from "./symbols";
|
|
3
|
-
/**
|
|
4
|
-
* Stops the observer that created it when called.
|
|
5
|
-
*/
|
|
6
|
-
export type StopFunction = () => void;
|
|
7
|
-
type Unwrapped<T> = T extends State<infer V> ? V : T;
|
|
8
|
-
/**
|
|
9
|
-
* Extracts value types from an array of states.
|
|
10
|
-
*/
|
|
11
|
-
export type StateValues<T extends MaybeState<any>[]> = {
|
|
12
|
-
[K in keyof T]: Unwrapped<T[K]>;
|
|
13
|
-
};
|
|
14
|
-
export interface CreateStateOptions<T> {
|
|
15
|
-
/**
|
|
16
|
-
* Determines if the `next` value is equal to the `current` value.
|
|
17
|
-
* If this function returns true, watchers will be notified of changes. If it returns false, watchers will not be notified.
|
|
18
|
-
* Default equals check is `===` (strict) equality.
|
|
19
|
-
*
|
|
20
|
-
* @param next - The new value being set.
|
|
21
|
-
* @param current - The current value being replaced.
|
|
22
|
-
*/
|
|
23
|
-
equals?: (next: T, current: T) => boolean;
|
|
24
|
-
}
|
|
25
|
-
export interface WatchOptions<T> {
|
|
26
|
-
/**
|
|
27
|
-
* If true the watch callback will be called for the first time on the next change.
|
|
28
|
-
* Callback is immediately called with the state's current value by default.
|
|
29
|
-
*/
|
|
30
|
-
lazy?: boolean;
|
|
31
|
-
}
|
|
32
|
-
export interface State<T> {
|
|
33
|
-
/**
|
|
34
|
-
* Returns the current value.
|
|
35
|
-
*/
|
|
36
|
-
get(): T;
|
|
37
|
-
/**
|
|
38
|
-
* Watch this state's value with a `callback` function.
|
|
39
|
-
* The `callback` is only called if the value is not equal to the current value.
|
|
40
|
-
*
|
|
41
|
-
* > NOTE: If watching a state inside a view, use the `.watch` method on the `ViewContext`. That method will automatically
|
|
42
|
-
* clean up all watchers when the view is disconnected. Watchers created here must be cleaned up manually.
|
|
43
|
-
*/
|
|
44
|
-
watch(callback: (value: T) => void, options?: WatchOptions<T>): StopFunction;
|
|
45
|
-
}
|
|
46
|
-
/** A new value for a state, or a callback that receives the current value and returns a new one. */
|
|
47
|
-
export type SetAction<I, O = I> = O | SetFunction<I, O>;
|
|
48
|
-
export type SetFunction<I, O = I> = (current: I) => O;
|
|
49
|
-
/** Callback that updates the value of a state. */
|
|
50
|
-
export type Setter<I, O = I> = (value: SetAction<I, O>) => void;
|
|
51
|
-
export type MaybeState<T> = State<T> | T;
|
|
52
|
-
export declare function isState<T>(value: any): value is State<T>;
|
|
53
|
-
/**
|
|
54
|
-
* Retrieves a plain value from a variable that may be a state.
|
|
55
|
-
*/
|
|
56
|
-
export declare function toValue<T>(source: MaybeState<T>): T;
|
|
57
|
-
/**
|
|
58
|
-
* Ensures a variable that may be a state or plain value is a state.
|
|
59
|
-
*/
|
|
60
|
-
export declare function toState<T>(value: MaybeState<T>): State<T>;
|
|
61
|
-
/**
|
|
62
|
-
* ValueHolder implements the core functionality of a State.
|
|
63
|
-
* It holds a value, which can be retrieved with `get`, updated with `set` and observed with `watch`.
|
|
64
|
-
* The user-facing API splits up access into a read-only State and a setter function.
|
|
65
|
-
*/
|
|
66
|
-
export declare class ValueHolder<T> implements State<T> {
|
|
67
|
-
value: T;
|
|
68
|
-
watchers: ((value: T) => void)[];
|
|
69
|
-
equals: typeof strictEqual;
|
|
70
|
-
constructor(value: T, options?: CreateStateOptions<T>);
|
|
71
|
-
get(): T;
|
|
72
|
-
set(action: T | SetFunction<T>): void;
|
|
73
|
-
watch(callback: (value: T) => void, options?: WatchOptions<T>): () => void;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Signal is the implementation of a read-only State.
|
|
77
|
-
*/
|
|
78
|
-
export declare class Signal<T> implements State<T> {
|
|
79
|
-
[IS_STATE]: boolean;
|
|
80
|
-
__value: State<T>;
|
|
81
|
-
constructor(value: State<T>);
|
|
82
|
-
get(): T;
|
|
83
|
-
watch(callback: (value: T) => void, options?: WatchOptions<T>): StopFunction;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Creates a state and setter.
|
|
87
|
-
*/
|
|
88
|
-
export declare function createState<T>(value: T, options?: CreateStateOptions<T>): [State<T>, Setter<T>];
|
|
89
|
-
/**
|
|
90
|
-
* Creates a state and setter.
|
|
91
|
-
*/
|
|
92
|
-
export declare function createState<T>(value?: T, options?: CreateStateOptions<T | undefined>): [State<T | undefined>, Setter<T | undefined>];
|
|
93
|
-
export interface DeriveOptions {
|
|
94
|
-
equals?: (next: unknown, current: unknown) => boolean;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Derives a new `State` from one or more existing states.
|
|
98
|
-
*
|
|
99
|
-
* @param sources - Array of source states to track.
|
|
100
|
-
* @param fn - A function called to recompute the value when any tracked source states receive a new value.
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* // With one source...
|
|
104
|
-
* const [$count, setCount] = createState(5);
|
|
105
|
-
* const $doubled = derive([$count], count => count * 2);
|
|
106
|
-
* // ... or many:
|
|
107
|
-
* const [$greeting, setGreeting] = createState("Hello");
|
|
108
|
-
* const [$name, setName] = createState("World");
|
|
109
|
-
* const $hello = derive([$greeting, name], (greeting, name) => `${greeting}, ${name}!`);
|
|
110
|
-
*/
|
|
111
|
-
export declare function derive<Sources extends MaybeState<any>[], T>(sources: [...Sources], fn: (...values: StateValues<Sources>) => T | State<T>, options?: DeriveOptions): State<T>;
|
|
112
|
-
export interface StateWatcher {
|
|
113
|
-
/**
|
|
114
|
-
* Watch one or more states, calling the provided `fn` each time one of their values changes.
|
|
115
|
-
*
|
|
116
|
-
* @param states - An array of states or plain values. States will be unwrapped before being passed to `fn`.
|
|
117
|
-
* @param fn - A function that takes the values of `states` in the same order they were passed.
|
|
118
|
-
*/
|
|
119
|
-
watch<I extends MaybeState<any>[]>(states: [...I], fn: (...currentValues: StateValues<I>) => void): StopFunction;
|
|
120
|
-
/**
|
|
121
|
-
* Stop all watch callbacks registered to this watcher.
|
|
122
|
-
*/
|
|
123
|
-
stopAll(): void;
|
|
124
|
-
}
|
|
125
|
-
export declare function createWatcher(): StateWatcher;
|
|
126
|
-
export {};
|
package/dist/core/stats.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Emitter } from "@manyducks.co/emitter";
|
|
2
|
-
import type { Dolla } from "./dolla";
|
|
3
|
-
interface StatsStore {
|
|
4
|
-
emitter: Emitter<StatsStoreEvents>;
|
|
5
|
-
stats: {
|
|
6
|
-
watcherCount: number;
|
|
7
|
-
viewCount: number;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
type StatsStoreEvents = {
|
|
11
|
-
/**
|
|
12
|
-
* Emitted when any stats are updated in the store.
|
|
13
|
-
*/
|
|
14
|
-
statsChanged: [];
|
|
15
|
-
_incrementWatcherCount: [amount: number];
|
|
16
|
-
_incrementViewCount: [amount: number];
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Tracks runtime statistics.
|
|
20
|
-
*/
|
|
21
|
-
export declare class Stats {
|
|
22
|
-
#private;
|
|
23
|
-
constructor(dolla: Dolla);
|
|
24
|
-
}
|
|
25
|
-
export declare function _createStore(): StatsStore;
|
|
26
|
-
export declare function _getStore(): StatsStore;
|
|
27
|
-
export declare function _onWatcherAdded(): void;
|
|
28
|
-
export declare function _onWatcherRemoved(): void;
|
|
29
|
-
export declare function _onViewMounted(): void;
|
|
30
|
-
export declare function _onViewUnmounted(): void;
|
|
31
|
-
export {};
|