@manyducks.co/dolla 1.1.0 → 2.0.0-alpha.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 +47 -23
- package/build.js +5 -5
- package/dist/fragment-DHJiX0-a.js +1241 -0
- package/dist/fragment-DHJiX0-a.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +1331 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx-dev-runtime.js +17 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/{lib/jsx → dist}/jsx-runtime.d.ts +3 -4
- package/dist/jsx-runtime.js +20 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/{lib → dist}/markup.d.ts +18 -13
- package/dist/modules/dolla.d.ts +87 -0
- package/dist/modules/http.d.ts +57 -0
- package/dist/modules/language.d.ts +41 -0
- package/{lib/stores → dist/modules}/render.d.ts +5 -6
- package/{lib/stores → dist/modules}/router.d.ts +37 -39
- package/{lib → dist}/nodes/cond.d.ts +1 -4
- package/{lib → dist}/nodes/html.d.ts +2 -5
- package/{lib → dist}/nodes/observer.d.ts +2 -5
- package/{lib → dist}/nodes/outlet.d.ts +1 -4
- package/{lib → dist}/nodes/portal.d.ts +1 -3
- package/{lib → dist}/nodes/repeat.d.ts +2 -5
- package/{lib → dist}/nodes/text.d.ts +1 -1
- package/{lib → dist}/signals.d.ts +35 -46
- package/{lib → dist}/types.d.ts +0 -8
- package/{lib → dist}/utils.d.ts +10 -0
- package/dist/view.d.ts +44 -0
- package/dist/views/default-crash-page.d.ts +8 -0
- package/notes/scratch.md +120 -0
- package/package.json +12 -12
- package/vite.config.js +27 -0
- package/lib/app.d.ts +0 -83
- package/lib/classes/CrashCollector.d.ts +0 -30
- package/lib/classes/DebugHub.d.ts +0 -61
- package/lib/classes/EventEmitter.d.ts +0 -44
- package/lib/index.d.ts +0 -21
- package/lib/index.js +0 -4176
- package/lib/index.js.map +0 -7
- package/lib/jsx/jsx-dev-runtime.d.ts +0 -3
- package/lib/jsx/jsx-dev-runtime.js +0 -20
- package/lib/jsx/jsx-dev-runtime.js.map +0 -7
- package/lib/jsx/jsx-runtime.js +0 -22
- package/lib/jsx/jsx-runtime.js.map +0 -7
- package/lib/signals.test.d.ts +0 -1
- package/lib/spring.d.ts +0 -0
- package/lib/state.d.ts +0 -103
- package/lib/store.d.ts +0 -59
- package/lib/stores/dialog.d.ts +0 -32
- package/lib/stores/document.d.ts +0 -11
- package/lib/stores/http.d.ts +0 -60
- package/lib/stores/language.d.ts +0 -36
- package/lib/testing/classes/MockHTTP.d.ts +0 -10
- package/lib/testing/index.d.ts +0 -4
- package/lib/testing/makeMockDOMNode.d.ts +0 -10
- package/lib/testing/makeMockFetch._test.d.ts +0 -1
- package/lib/testing/makeMockFetch.d.ts +0 -36
- package/lib/testing/makeMockFetch.test.d.ts +0 -1
- package/lib/testing/makeMockFetch.test_skip.d.ts +0 -1
- package/lib/testing/stores/dialog.d.ts +0 -6
- package/lib/testing/stores/http.d.ts +0 -13
- package/lib/testing/stores/page.d.ts +0 -7
- package/lib/testing/stores/router.d.ts +0 -12
- package/lib/testing/wrapStore._test.d.ts +0 -1
- package/lib/testing/wrapStore.d.ts +0 -8
- package/lib/testing/wrapStore.test.d.ts +0 -1
- package/lib/testing/wrapStore.test_skip.d.ts +0 -1
- package/lib/testing/wrapView.d.ts +0 -0
- package/lib/view.d.ts +0 -88
- package/lib/views/default-crash-page.d.ts +0 -7
- package/lib/views/store-scope.d.ts +0 -13
- /package/{lib → dist}/routing.d.ts +0 -0
- /package/{lib → dist}/routing.test.d.ts +0 -0
- /package/{lib → dist}/typeChecking.d.ts +0 -0
- /package/{lib → dist}/views/default-view.d.ts +0 -0
- /package/{lib → dist}/views/fragment.d.ts +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Signal } from "../signals.js";
|
|
2
|
+
import type { Stringable } from "../types.js";
|
|
3
|
+
import type { Dolla } from "./dolla.js";
|
|
4
|
+
/**
|
|
5
|
+
* An object where values are either a translated string or another nested Translation object.
|
|
6
|
+
*/
|
|
7
|
+
type LocalizedStrings = Record<string, string | Record<string, string | Record<string, string | Record<string, string>>>>;
|
|
8
|
+
export interface LanguageConfig {
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* Path to a JSON file with translated strings for this language.
|
|
12
|
+
*/
|
|
13
|
+
path?: string;
|
|
14
|
+
/**
|
|
15
|
+
* A callback function that returns a Promise that resolves to the translation object for this language.
|
|
16
|
+
*/
|
|
17
|
+
fetch?: () => Promise<LocalizedStrings>;
|
|
18
|
+
}
|
|
19
|
+
export type LanguageSetupOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* Default language to load on startup
|
|
22
|
+
*/
|
|
23
|
+
initialLanguage?: string | null;
|
|
24
|
+
languages: LanguageConfig[];
|
|
25
|
+
};
|
|
26
|
+
export declare class Language {
|
|
27
|
+
#private;
|
|
28
|
+
$current: Signal<string | undefined>;
|
|
29
|
+
constructor(dolla: Dolla);
|
|
30
|
+
get supportedLanguages(): string[];
|
|
31
|
+
setup(options: LanguageSetupOptions): void;
|
|
32
|
+
setLanguage(name: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns a Signal containing the value at `key`.
|
|
35
|
+
|
|
36
|
+
* @param key - Key to the translated value.
|
|
37
|
+
* @param values - A map of {{placeholder}} names and the values to replace them with.
|
|
38
|
+
*/
|
|
39
|
+
t(key: string, values?: Record<string, Stringable | Signal<Stringable>>): Signal<string>;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare function RenderStore(ctx: StoreContext): {
|
|
1
|
+
import type { Dolla } from "./dolla.js";
|
|
2
|
+
export declare class Render {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(dolla: Dolla);
|
|
6
5
|
/**
|
|
7
6
|
* Queues a callback to run in the next render batch.
|
|
8
7
|
* Running your DOM mutations in update callbacks reduces layout thrashing.
|
|
@@ -15,4 +14,4 @@ export declare function RenderStore(ctx: StoreContext): {
|
|
|
15
14
|
* Returns a Promise that resolves once the callback has run.
|
|
16
15
|
*/
|
|
17
16
|
read(callback: () => void): Promise<void>;
|
|
18
|
-
}
|
|
17
|
+
}
|
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type
|
|
3
|
-
import { type
|
|
4
|
-
import
|
|
5
|
-
import { type View } from "../view.js";
|
|
1
|
+
import { type DOMHandle, type Markup } from "../markup.js";
|
|
2
|
+
import { type Stringable } from "../types.js";
|
|
3
|
+
import { type ViewFunction } from "../view.js";
|
|
4
|
+
import type { Dolla } from "./dolla.js";
|
|
6
5
|
export interface RouteMatchContext {
|
|
7
|
-
/**
|
|
8
|
-
* Returns the shared instance of `store`.
|
|
9
|
-
*/
|
|
10
|
-
getStore<T extends Store<any, any>>(store: T): ReturnType<T>;
|
|
11
|
-
/**
|
|
12
|
-
* Returns the shared instance of a built-in store.
|
|
13
|
-
*/
|
|
14
|
-
getStore<N extends keyof BuiltInStores>(name: N): BuiltInStores[N];
|
|
15
6
|
/**
|
|
16
7
|
* Redirects the user to a different route instead of matching the current one.
|
|
17
8
|
*/
|
|
@@ -29,7 +20,7 @@ export interface Route {
|
|
|
29
20
|
/**
|
|
30
21
|
* View to display when this route is matched.
|
|
31
22
|
*/
|
|
32
|
-
view?:
|
|
23
|
+
view?: ViewFunction<any>;
|
|
33
24
|
/**
|
|
34
25
|
* Subroutes.
|
|
35
26
|
*/
|
|
@@ -78,7 +69,7 @@ interface ParsedParams {
|
|
|
78
69
|
}
|
|
79
70
|
interface ParsedQuery extends ParsedParams {
|
|
80
71
|
}
|
|
81
|
-
interface NavigateOptions {
|
|
72
|
+
export interface NavigateOptions {
|
|
82
73
|
/**
|
|
83
74
|
* Replace the current item in the history stack instead of adding a new one.
|
|
84
75
|
* The back button will send the user to the page they visited before this. Defaults to false.
|
|
@@ -89,20 +80,31 @@ interface NavigateOptions {
|
|
|
89
80
|
*/
|
|
90
81
|
preserveQuery?: boolean;
|
|
91
82
|
}
|
|
92
|
-
|
|
93
|
-
routes: Route[];
|
|
83
|
+
export declare enum RoutingStyle {
|
|
94
84
|
/**
|
|
95
|
-
*
|
|
85
|
+
* Constructs routes like "https://www.example.com/#/sub/route" which work without any server-side setup.
|
|
86
|
+
* A good choice if your app has no backend.
|
|
96
87
|
*/
|
|
97
|
-
hash
|
|
88
|
+
hash = "hash",
|
|
98
89
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
|
|
90
|
+
* Constructs routes like "https://www.example.com/sub/route" which look nicer (subjective?) than hash routes and are what most users will expect URLs to look like, but require additional backend setup.
|
|
91
|
+
* Path routing requires you to configure your backend to redirect to the app's index.html when subpaths are requested.
|
|
92
|
+
*/
|
|
93
|
+
path = "path"
|
|
94
|
+
}
|
|
95
|
+
export interface RouterSetupOptions {
|
|
96
|
+
routes: Route[];
|
|
97
|
+
/**
|
|
98
|
+
* The routing style to use; "hash" will construct routes like "https://www.example.com/#/sub/route" which work without any server-side setup, while "path" will construct routes that use paths directly.
|
|
102
99
|
*/
|
|
103
|
-
|
|
100
|
+
style?: RoutingStyle;
|
|
101
|
+
}
|
|
102
|
+
export interface RouterElements {
|
|
103
|
+
readonly rootElement?: HTMLElement;
|
|
104
|
+
readonly rootView?: DOMHandle;
|
|
104
105
|
}
|
|
105
|
-
export declare
|
|
106
|
+
export declare class Router {
|
|
107
|
+
#private;
|
|
106
108
|
/**
|
|
107
109
|
* The currently matched route pattern, if any.
|
|
108
110
|
*/
|
|
@@ -119,7 +121,16 @@ export declare function RouterStore(ctx: StoreContext<RouterStoreOptions>): {
|
|
|
119
121
|
* The current query params. Changes to this object will be reflected in the URL.
|
|
120
122
|
*/
|
|
121
123
|
$query: import("../signals.js").Signal<ParsedQuery>;
|
|
122
|
-
|
|
124
|
+
constructor(dolla: Dolla, elements: RouterElements);
|
|
125
|
+
setup(options: RouterSetupOptions): void;
|
|
126
|
+
/**
|
|
127
|
+
* Navigates to another route.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* navigate("/login"); // navigate to `/login`
|
|
131
|
+
* navigate(["/users", 215], { replace: true }); // replace current history entry with `/users/215`
|
|
132
|
+
*/
|
|
133
|
+
go(path: Stringable | Stringable[], options?: NavigateOptions): void;
|
|
123
134
|
/**
|
|
124
135
|
* Navigate backward. Pass a number of steps to hit the back button that many times.
|
|
125
136
|
*/
|
|
@@ -128,20 +139,7 @@ export declare function RouterStore(ctx: StoreContext<RouterStoreOptions>): {
|
|
|
128
139
|
* Navigate forward. Pass a number of steps to hit the forward button that many times.
|
|
129
140
|
*/
|
|
130
141
|
forward(steps?: number): void;
|
|
131
|
-
|
|
132
|
-
* Navigates to another route.
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* navigate("/login"); // navigate to `/login`
|
|
136
|
-
* navigate(["/users", 215], { replace: true }); // replace current history entry with `/users/215`
|
|
137
|
-
*
|
|
138
|
-
* @param args - One or more path segments optionally followed by an options object.
|
|
139
|
-
*/
|
|
140
|
-
navigate: {
|
|
141
|
-
(path: Stringable, options?: NavigateOptions): void;
|
|
142
|
-
(fragments: Stringable[], options?: NavigateOptions): void;
|
|
143
|
-
};
|
|
144
|
-
};
|
|
142
|
+
}
|
|
145
143
|
/**
|
|
146
144
|
* Intercepts links within the root node.
|
|
147
145
|
*
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle, type Markup } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext, type Markup } from "../markup.js";
|
|
3
2
|
import { type Signal, type StopFunction } from "../signals.js";
|
|
4
3
|
import { type Renderable } from "../types.js";
|
|
5
4
|
export interface ConditionalConfig {
|
|
6
5
|
$predicate: Signal<any>;
|
|
7
6
|
thenContent?: Renderable;
|
|
8
7
|
elseContent?: Renderable;
|
|
9
|
-
appContext: AppContext;
|
|
10
8
|
elementContext: ElementContext;
|
|
11
9
|
}
|
|
12
10
|
export declare class Conditional implements DOMHandle {
|
|
@@ -17,7 +15,6 @@ export declare class Conditional implements DOMHandle {
|
|
|
17
15
|
thenContent?: Markup[];
|
|
18
16
|
elseContent?: Markup[];
|
|
19
17
|
connectedContent: DOMHandle[];
|
|
20
|
-
appContext: AppContext;
|
|
21
18
|
elementContext: ElementContext;
|
|
22
19
|
initialUpdateHappened: boolean;
|
|
23
20
|
previousValue?: any;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle, type Markup } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext, type Markup } from "../markup.js";
|
|
3
2
|
import { type StopFunction } from "../signals.js";
|
|
4
3
|
type HTMLOptions = {
|
|
5
|
-
appContext: AppContext;
|
|
6
4
|
elementContext: ElementContext;
|
|
7
5
|
tag: string;
|
|
8
6
|
props?: any;
|
|
@@ -13,12 +11,11 @@ export declare class HTML implements DOMHandle {
|
|
|
13
11
|
props: Record<string, any>;
|
|
14
12
|
children: DOMHandle[];
|
|
15
13
|
stopCallbacks: StopFunction[];
|
|
16
|
-
appContext: AppContext;
|
|
17
14
|
elementContext: ElementContext;
|
|
18
15
|
uniqueId: string;
|
|
19
16
|
canClickAway: boolean;
|
|
20
17
|
get connected(): boolean;
|
|
21
|
-
constructor({ tag, props, children,
|
|
18
|
+
constructor({ tag, props, children, elementContext }: HTMLOptions);
|
|
22
19
|
connect(parent: Node, after?: Node): void;
|
|
23
20
|
disconnect(): void;
|
|
24
21
|
setChildren(next: DOMHandle[]): void;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext } from "../markup.js";
|
|
3
2
|
import { type Signal } from "../signals.js";
|
|
4
3
|
import type { Renderable } from "../types.js";
|
|
5
4
|
interface ObserverOptions {
|
|
6
|
-
appContext: AppContext;
|
|
7
5
|
elementContext: ElementContext;
|
|
8
6
|
signals: Signal<any>[];
|
|
9
7
|
renderFn: (...values: any) => Renderable;
|
|
@@ -16,14 +14,13 @@ export declare class Observer implements DOMHandle {
|
|
|
16
14
|
endNode: Node;
|
|
17
15
|
connectedViews: DOMHandle[];
|
|
18
16
|
renderFn: (...values: any) => Renderable;
|
|
19
|
-
appContext: AppContext;
|
|
20
17
|
elementContext: ElementContext;
|
|
21
18
|
observerControls: {
|
|
22
19
|
start: () => void;
|
|
23
20
|
stop: () => void;
|
|
24
21
|
};
|
|
25
22
|
get connected(): boolean;
|
|
26
|
-
constructor({ signals, renderFn,
|
|
23
|
+
constructor({ signals, renderFn, elementContext }: ObserverOptions);
|
|
27
24
|
connect(parent: Node, after?: Node): void;
|
|
28
25
|
disconnect(): void;
|
|
29
26
|
setChildren(): Promise<void>;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext } from "../markup.js";
|
|
3
2
|
import { type Signal, type StopFunction } from "../signals.js";
|
|
4
3
|
export interface OutletConfig {
|
|
5
4
|
$children: Signal<DOMHandle[]>;
|
|
6
|
-
appContext: AppContext;
|
|
7
5
|
elementContext: ElementContext;
|
|
8
6
|
}
|
|
9
7
|
/**
|
|
@@ -15,7 +13,6 @@ export declare class Outlet implements DOMHandle {
|
|
|
15
13
|
$children: Signal<DOMHandle[]>;
|
|
16
14
|
stopCallback?: StopFunction;
|
|
17
15
|
connectedChildren: DOMHandle[];
|
|
18
|
-
appContext: AppContext;
|
|
19
16
|
elementContext: ElementContext;
|
|
20
17
|
constructor(config: OutletConfig);
|
|
21
18
|
get connected(): boolean;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext } from "../markup.js";
|
|
3
2
|
import { type Renderable } from "../types.js";
|
|
4
3
|
interface PortalConfig {
|
|
5
4
|
content: Renderable;
|
|
6
5
|
parent: Node;
|
|
7
|
-
appContext: AppContext;
|
|
8
6
|
elementContext: ElementContext;
|
|
9
7
|
}
|
|
10
8
|
/**
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type DOMHandle } from "../markup.js";
|
|
1
|
+
import { type DOMHandle, type ElementContext } from "../markup.js";
|
|
3
2
|
import { type Signal, type SignalSetter, type StopFunction } from "../signals.js";
|
|
4
3
|
import { type ViewContext, type ViewResult } from "../view.js";
|
|
5
4
|
interface RepeatOptions<T> {
|
|
6
|
-
appContext: AppContext;
|
|
7
5
|
elementContext: ElementContext;
|
|
8
6
|
$items: Signal<T[]>;
|
|
9
7
|
keyFn: (value: T, index: number) => string | number | symbol;
|
|
@@ -23,12 +21,11 @@ export declare class Repeat<T> implements DOMHandle {
|
|
|
23
21
|
$items: Signal<T[]>;
|
|
24
22
|
stopCallback?: StopFunction;
|
|
25
23
|
connectedItems: ConnectedItem<T>[];
|
|
26
|
-
appContext: AppContext;
|
|
27
24
|
elementContext: ElementContext;
|
|
28
25
|
renderFn: ($value: Signal<T>, $index: Signal<number>, ctx: ViewContext) => ViewResult;
|
|
29
26
|
keyFn: (value: T, index: number) => string | number | symbol;
|
|
30
27
|
get connected(): boolean;
|
|
31
|
-
constructor({
|
|
28
|
+
constructor({ elementContext, $items, renderFn, keyFn }: RepeatOptions<T>);
|
|
32
29
|
connect(parent: Node, after?: Node): void;
|
|
33
30
|
disconnect(): void;
|
|
34
31
|
setChildren(): void;
|
|
@@ -9,16 +9,16 @@ type Unwrapped<T> = T extends Signal<infer V> ? V : T;
|
|
|
9
9
|
export type SignalValues<T extends MaybeSignal<any>[]> = {
|
|
10
10
|
[K in keyof T]: Unwrapped<T[K]>;
|
|
11
11
|
};
|
|
12
|
-
export interface
|
|
12
|
+
export interface CreateSignalOptions<T> {
|
|
13
13
|
/**
|
|
14
|
-
* Determines if the `next` value is equal to the `
|
|
14
|
+
* Determines if the `next` value is equal to the `current` value.
|
|
15
15
|
* If this function returns true, watchers will be notified of changes. If it returns false, watchers will not be notified.
|
|
16
16
|
* By default equality is defined as deep equality.
|
|
17
17
|
*
|
|
18
18
|
* @param next - The new value being set.
|
|
19
|
-
* @param
|
|
19
|
+
* @param current - The current value being replaced.
|
|
20
20
|
*/
|
|
21
|
-
equality?: (next: T,
|
|
21
|
+
equality?: (next: T, current: T) => boolean;
|
|
22
22
|
}
|
|
23
23
|
export interface SignalWatchOptions<T> {
|
|
24
24
|
/**
|
|
@@ -34,7 +34,7 @@ export interface Signal<T> {
|
|
|
34
34
|
get(): T;
|
|
35
35
|
/**
|
|
36
36
|
* Watch this signal's value with a `callback` function.
|
|
37
|
-
* The `callback` is only called if the value is not equal to the
|
|
37
|
+
* The `callback` is only called if the value is not equal to the current value.
|
|
38
38
|
*
|
|
39
39
|
* > NOTE: If watching a signal inside a view, use the `.watch` method on the `ViewContext`. That method will automatically
|
|
40
40
|
* clean up all watchers when the view is disconnected. Watchers created here must be cleaned up manually.
|
|
@@ -42,9 +42,9 @@ export interface Signal<T> {
|
|
|
42
42
|
watch(callback: (value: T) => void, options?: SignalWatchOptions<T>): StopFunction;
|
|
43
43
|
}
|
|
44
44
|
/** A new value for a signal, or a callback that receives the current value and returns a new one. */
|
|
45
|
-
export type
|
|
45
|
+
export type SignalSetAction<I, O = I> = O | ((current: I) => O);
|
|
46
46
|
/** Callback that updates the value of a signal. */
|
|
47
|
-
export type SignalSetter<I, O = I> = (value:
|
|
47
|
+
export type SignalSetter<I, O = I> = (value: SignalSetAction<I, O>) => void;
|
|
48
48
|
export type MaybeSignal<T> = Signal<T> | T;
|
|
49
49
|
/**
|
|
50
50
|
* A signal and setter in one. Useful for passing signals that are intended to be updated by subviews.
|
|
@@ -57,7 +57,7 @@ export interface SettableSignal<I, O = I> extends Signal<I> {
|
|
|
57
57
|
/**
|
|
58
58
|
* Takes a callback that recieves the signal's current value and returns a new one.
|
|
59
59
|
*/
|
|
60
|
-
set(callback: (
|
|
60
|
+
set(callback: (current: I) => O): void;
|
|
61
61
|
}
|
|
62
62
|
export declare function isSignal<T>(value: any): value is Signal<T>;
|
|
63
63
|
export declare function isSettableSignal<T>(value: any): value is Signal<T>;
|
|
@@ -69,44 +69,33 @@ export declare function designalify<T>(value: MaybeSignal<T>): T;
|
|
|
69
69
|
* Ensures a variable that may be a signal or plain value is a signal.
|
|
70
70
|
*/
|
|
71
71
|
export declare function signalify<T>(value: MaybeSignal<T>): Signal<T>;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
export
|
|
97
|
-
|
|
98
|
-
export declare namespace signal {
|
|
99
|
-
var settable: typeof createSettableSignal;
|
|
100
|
-
var toSettable: typeof createSettableSignalFrom;
|
|
101
|
-
var createSetter: typeof createSignalSetter;
|
|
102
|
-
}
|
|
103
|
-
declare function createSettableSignal<T>(initialValue: T, options?: SignalCreateOptions<T>): SettableSignal<T>;
|
|
104
|
-
declare function createSettableSignal<T>(initialValue?: T, options?: SignalCreateOptions<T | undefined>): SettableSignal<T | undefined>;
|
|
105
|
-
declare function createSettableSignalFrom<I, O = I>(signal: Signal<I>, setter: SignalSetter<I, O>): SettableSignal<I, O>;
|
|
106
|
-
declare function createSignalSetter<I, O = I>(signal: Signal<I>, callback: (next: O, previous: I) => void): SignalSetter<I, O>;
|
|
107
|
-
export interface SignalDeriveOptions {
|
|
108
|
-
equality?: (next: unknown, previous: unknown) => boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Creates a SettableSignal.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createSettableSignal<T>(initialValue: T, options?: CreateSignalOptions<T>): SettableSignal<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Creates a SettableSignal.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createSettableSignal<T>(initialValue?: T, options?: CreateSignalOptions<T | undefined>): SettableSignal<T | undefined>;
|
|
80
|
+
/**
|
|
81
|
+
* Join a signal and its setter into a single SettableSignal object.
|
|
82
|
+
*/
|
|
83
|
+
export declare function toSettableSignal<I, O = I>(signal: Signal<I>, setter: SignalSetter<I, O>): SettableSignal<I, O>;
|
|
84
|
+
/**
|
|
85
|
+
* Creates a SignalSetter with custom logic provided by `callback`.
|
|
86
|
+
*/
|
|
87
|
+
export declare function createSignalSetter<I, O = I>(signal: Signal<I>, callback: (next: O, current: I) => void): SignalSetter<I, O>;
|
|
88
|
+
/**
|
|
89
|
+
* Creates a signal and setter.
|
|
90
|
+
*/
|
|
91
|
+
export declare function createSignal<T>(initialValue: T, options?: CreateSignalOptions<T>): [Signal<T>, SignalSetter<T>];
|
|
92
|
+
/**
|
|
93
|
+
* Creates a signal and setter.
|
|
94
|
+
*/
|
|
95
|
+
export declare function createSignal<T>(initialValue?: T, options?: CreateSignalOptions<T | undefined>): [Signal<T | undefined>, SignalSetter<T | undefined>];
|
|
96
|
+
export interface DeriveSignalOptions {
|
|
97
|
+
equality?: (next: unknown, current: unknown) => boolean;
|
|
109
98
|
}
|
|
110
|
-
export declare function derive<Inputs extends MaybeSignal<any>[], T>(signals: [...Inputs], fn: (...currentValues: SignalValues<Inputs>) => T | Signal<T>, options?:
|
|
99
|
+
export declare function derive<Inputs extends MaybeSignal<any>[], T>(signals: [...Inputs], fn: (...currentValues: SignalValues<Inputs>) => T | Signal<T>, options?: DeriveSignalOptions): Signal<T>;
|
|
111
100
|
export declare function watch<I extends MaybeSignal<any>[]>(signals: [...I], fn: (...currentValues: SignalValues<I>) => void): StopFunction;
|
|
112
101
|
export {};
|
package/{lib → dist}/types.d.ts
RENAMED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import type * as CSS from "csstype";
|
|
2
2
|
import { Ref, type Markup } from "./markup.js";
|
|
3
|
-
import { type Store } from "./store.js";
|
|
4
|
-
import { type DocumentStore } from "./stores/document.js";
|
|
5
|
-
import { type RenderStore } from "./stores/render.js";
|
|
6
3
|
import { SettableSignal, Signal } from "./signals.js";
|
|
7
4
|
/**
|
|
8
5
|
* Represents everything that can be handled as a DOM node.
|
|
9
6
|
* These are all the items considered valid to pass as children to any element.
|
|
10
7
|
*/
|
|
11
8
|
export type Renderable = string | number | Markup | false | null | undefined | Signal<any> | (string | number | Markup | false | null | undefined | Signal<any>)[];
|
|
12
|
-
export type StoreExports<T> = T extends Store<any, infer O> ? O : unknown;
|
|
13
|
-
export interface BuiltInStores {
|
|
14
|
-
document: StoreExports<typeof DocumentStore>;
|
|
15
|
-
render: StoreExports<typeof RenderStore>;
|
|
16
|
-
}
|
|
17
9
|
export type Stringable = {
|
|
18
10
|
toString(): string;
|
|
19
11
|
};
|
package/{lib → dist}/utils.d.ts
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const noOp: () => void;
|
|
1
2
|
export declare function deepEqual(one: any, two: any): boolean;
|
|
2
3
|
/**
|
|
3
4
|
* Takes an old value and a new value. Returns a merged copy if both are objects, otherwise returns the new value.
|
|
@@ -12,3 +13,12 @@ export declare function merge(one: unknown, two: unknown): any;
|
|
|
12
13
|
* @param object - An object to clone without the omitted keys.
|
|
13
14
|
*/
|
|
14
15
|
export declare function omit<O extends Record<any, any>>(keys: (keyof O)[], object: O): Record<any, any>;
|
|
16
|
+
export declare function getDefaultConsole(): any;
|
|
17
|
+
export declare function colorFromString(value: string): string;
|
|
18
|
+
export type MatcherFunction = (value: string) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Parses a filter string into a matcher function.
|
|
21
|
+
*
|
|
22
|
+
* @param pattern - A string or regular expression that specifies a pattern for names of loggers whose messages you want to display.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createMatcher(pattern: string | RegExp): MatcherFunction;
|
package/dist/view.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type DOMHandle, type ElementContext, type Markup } from "./markup.js";
|
|
2
|
+
import type { Logger } from "./modules/dolla.js";
|
|
3
|
+
import { type MaybeSignal, Signal, type SignalValues, type StopFunction } from "./signals.js";
|
|
4
|
+
/**
|
|
5
|
+
* Any valid value that a View can return.
|
|
6
|
+
*/
|
|
7
|
+
export type ViewResult = Node | Signal<any> | Markup | Markup[] | null;
|
|
8
|
+
export type ViewFunction<P> = (props: P, context: ViewContext) => ViewResult;
|
|
9
|
+
export interface ViewContext extends Logger {
|
|
10
|
+
/**
|
|
11
|
+
* A string ID unique to this view.
|
|
12
|
+
*/
|
|
13
|
+
readonly uid: string;
|
|
14
|
+
/**
|
|
15
|
+
* Sets the name of the view's built in logger.
|
|
16
|
+
*/
|
|
17
|
+
setName(name: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Registers a callback to run just before this view is mounted. DOM nodes are not yet attached to the page.
|
|
20
|
+
*/
|
|
21
|
+
beforeMount(callback: () => void): void;
|
|
22
|
+
/**
|
|
23
|
+
* Registers a callback to run just after this view is mounted.
|
|
24
|
+
*/
|
|
25
|
+
onMount(callback: () => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Registers a callback to run just before this view is unmounted. DOM nodes are still attached to the page.
|
|
28
|
+
*/
|
|
29
|
+
beforeUnmount(callback: () => void): void;
|
|
30
|
+
/**
|
|
31
|
+
* Registers a callback to run just after this view is unmounted.
|
|
32
|
+
*/
|
|
33
|
+
onUnmount(callback: () => void): void;
|
|
34
|
+
/**
|
|
35
|
+
* Watch a set of signals. The callback is called when any of the signals receive a new value.
|
|
36
|
+
* Watchers will be stopped when this view is unmounted. Returns a function to stop watching early.
|
|
37
|
+
*/
|
|
38
|
+
watch<T extends MaybeSignal<any>[]>(signals: [...T], callback: (...values: SignalValues<T>) => void): StopFunction;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a Markup element that displays this view's children.
|
|
41
|
+
*/
|
|
42
|
+
outlet(): Markup;
|
|
43
|
+
}
|
|
44
|
+
export declare function constructView<P>(elementContext: ElementContext, view: ViewFunction<P>, props: P, children?: Markup[]): DOMHandle;
|
package/notes/scratch.md
CHANGED
|
@@ -1,5 +1,125 @@
|
|
|
1
1
|
# Scratch Note
|
|
2
2
|
|
|
3
|
+
What if Dolla was just a global object that you don't instantiate. I have never personally run into a use case for having more than one app on a page at once. In all my projects, the page and the app are synonymous.
|
|
4
|
+
|
|
5
|
+
Doing this would make it possible to access things inside the Dolla app from _outside_ code such as Quill blots. Effectively all code that has access to your Dolla import is _inside_ the app.
|
|
6
|
+
|
|
7
|
+
- Remove stores in favor of just exporting variables and functions from ES modules and importing them where desired.
|
|
8
|
+
-
|
|
9
|
+
|
|
10
|
+
```jsx
|
|
11
|
+
import Dolla from "@manyducks.co/dolla";
|
|
12
|
+
|
|
13
|
+
// Languages: add translation, set language and get localized string as a signal
|
|
14
|
+
Dolla.language.setup({
|
|
15
|
+
initialLanguage: Dolla.language.detect({ fallback: "ja" }), // Detect user's language and fall back to passed value
|
|
16
|
+
languages: [
|
|
17
|
+
{ name: "ja", path: "/static/locales/ja.json" },
|
|
18
|
+
{
|
|
19
|
+
name: "en",
|
|
20
|
+
fetch: async () => {
|
|
21
|
+
// Pass a path string, or if additional logic is needed, a fetch function.
|
|
22
|
+
const res = await Dolla.http.get("/static/locales/en.json");
|
|
23
|
+
return res.body;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
Dolla.language.$current
|
|
30
|
+
Dolla.language.t$()
|
|
31
|
+
|
|
32
|
+
// A single setup call to keep things contained (must happen before mount)
|
|
33
|
+
Dolla.router.setup({
|
|
34
|
+
// Initial path must point to a route that actually exists (will be validated on mount) (initialPath is "/" by default)
|
|
35
|
+
initialPath: "/",
|
|
36
|
+
routes: [
|
|
37
|
+
{ path: "/", view: SomeView }
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
// And then you can route from anywhere.
|
|
41
|
+
Dolla.router.go("/some/path");
|
|
42
|
+
// Or get route information from anywhere.
|
|
43
|
+
Dolla.router.$path;
|
|
44
|
+
Dolla.router.$params;
|
|
45
|
+
|
|
46
|
+
// Also utils are available
|
|
47
|
+
const joinedPath = Dolla.router.utils.joinPath("/api/records", "5");
|
|
48
|
+
const resolvedPath = Dolla.router.utils.resolvePath("../"); // Resolves with window.location.href as the base
|
|
49
|
+
|
|
50
|
+
// Initializes the app and matches first route
|
|
51
|
+
Dolla.mount("#app");
|
|
52
|
+
// If you pass a view as the second argument it becomes the root view (this works for simple apps without a router)
|
|
53
|
+
Dolla.mount("#app", MyRootView);
|
|
54
|
+
// If router setup function wasn't called then the root view is mounted equivalent to the following:
|
|
55
|
+
Dolla.router.setup({
|
|
56
|
+
defaultPath: "/",
|
|
57
|
+
routes: [
|
|
58
|
+
{ path: "/*", view: MyRootView },
|
|
59
|
+
]
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Add HTTP middleware
|
|
63
|
+
Dolla.http.use(async (req, next) => {
|
|
64
|
+
const res = await next()
|
|
65
|
+
});
|
|
66
|
+
// Make HTTP calls
|
|
67
|
+
const res = await Dolla.get("/some/path");
|
|
68
|
+
|
|
69
|
+
// Adjust log level
|
|
70
|
+
Dolla.setLogLevel(Dolla.LOG_LEVEL_INFO);
|
|
71
|
+
Dolla.setLogFilter("*,-Dolla/*")
|
|
72
|
+
// Create a scoped logger
|
|
73
|
+
const debug = Dolla.createLogger("debug-logger");
|
|
74
|
+
debug.log("HELLO");
|
|
75
|
+
debug.warn("THIS IS A SCOPED LOGGER");
|
|
76
|
+
|
|
77
|
+
// Efficiently and safely read and mutate the DOM using Dolla's render batching
|
|
78
|
+
Dolla.render.read(() => {
|
|
79
|
+
// Reference DOM nodes
|
|
80
|
+
});
|
|
81
|
+
Dolla.render.update(() => {
|
|
82
|
+
// Mutate the DOM as part of Dolla's next batch
|
|
83
|
+
}, "some-key");
|
|
84
|
+
|
|
85
|
+
// Respond to lifecycle events
|
|
86
|
+
Dolla.onMount(() => {});
|
|
87
|
+
Dolla.onRouteMatch(() => {});
|
|
88
|
+
// Dolla.onWhatever(() => {});
|
|
89
|
+
|
|
90
|
+
interface SomeViewProps {}
|
|
91
|
+
|
|
92
|
+
function SomeView (props: SomeViewProps, ctx: Dolla.ViewContext) {
|
|
93
|
+
const debug = Dolla.createLogger("SomeView");
|
|
94
|
+
|
|
95
|
+
// returns a signal and a setter function
|
|
96
|
+
const [$someValue, setSomeValue] = Dolla.createSignal(4);
|
|
97
|
+
|
|
98
|
+
// Router is now a part of the Dolla object
|
|
99
|
+
Dolla.router.$path;
|
|
100
|
+
Dolla.router.$params;
|
|
101
|
+
|
|
102
|
+
Dolla.router.go("/some-other-path");
|
|
103
|
+
|
|
104
|
+
ctx.watch([$someValue], (value) => {
|
|
105
|
+
debug.log(value);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// View helpers are on ViewContext
|
|
109
|
+
ctx.repeat()
|
|
110
|
+
ctx.cond()
|
|
111
|
+
ctx.render([...states], (...values) => {
|
|
112
|
+
// return Renderable (equivalent to Dolla.derive(states, (...values) => Renderable))
|
|
113
|
+
})
|
|
114
|
+
ctx.portal()
|
|
115
|
+
ctx.outlet()
|
|
116
|
+
|
|
117
|
+
// TODO: Add Dolla.dialog.show() and Dolla.toast.show() or create separate libraries?
|
|
118
|
+
|
|
119
|
+
return <h1>{ctx.t$("home.headerText")}</h1>;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
3
123
|
```tsx
|
|
4
124
|
// import { signal, computed } from "@manyducks.co/dolla";
|
|
5
125
|
|