@manyducks.co/dolla 2.0.0 → 3.1.0
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 +133 -284
- package/dist/context-B5blupD2.js +363 -0
- package/dist/context-B5blupD2.js.map +1 -0
- package/dist/core/context.d.ts +29 -144
- package/dist/core/debug.d.ts +19 -0
- package/dist/core/index.d.ts +15 -16
- package/dist/core/markup/helpers.d.ts +34 -0
- package/dist/core/markup/html.d.ts +3 -0
- package/dist/core/{nodes → markup/nodes}/dom.d.ts +5 -4
- package/dist/core/markup/nodes/dynamic.d.ts +16 -0
- package/dist/core/markup/nodes/element.d.ts +14 -0
- package/dist/core/markup/nodes/portal.d.ts +15 -0
- package/dist/core/markup/nodes/repeat.d.ts +21 -0
- package/dist/core/markup/nodes/view.d.ts +17 -0
- package/dist/core/markup/scheduler.d.ts +1 -0
- package/dist/core/markup/types.d.ts +62 -0
- package/dist/core/markup/utils.d.ts +22 -0
- package/dist/core/ref.d.ts +6 -12
- package/dist/core/root.d.ts +36 -0
- package/dist/core/signals.d.ts +46 -76
- package/dist/core/symbols.d.ts +2 -0
- package/dist/core-JHktdqjt.js +242 -0
- package/dist/core-JHktdqjt.js.map +1 -0
- package/dist/http/index.d.ts +21 -33
- package/dist/http.js +89 -149
- package/dist/http.js.map +1 -1
- package/dist/index.js +4 -174
- package/dist/jsx-dev-runtime.d.ts +4 -3
- package/dist/jsx-dev-runtime.js +12 -9
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.d.ts +5 -4
- package/dist/jsx-runtime.js +17 -12
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/router/index.d.ts +4 -3
- package/dist/router/router.d.ts +19 -162
- package/dist/router/store.d.ts +12 -0
- package/dist/router/types.d.ts +152 -0
- package/dist/router/utils.d.ts +99 -0
- package/dist/router/utils.test.d.ts +1 -0
- package/dist/router.js +428 -5
- package/dist/router.js.map +1 -1
- package/dist/signals-CMJPGr_M.js +354 -0
- package/dist/signals-CMJPGr_M.js.map +1 -0
- package/dist/translate/index.d.ts +82 -0
- package/dist/translate.js +125 -0
- package/dist/translate.js.map +1 -0
- package/dist/types.d.ts +21 -39
- package/dist/utils.d.ts +41 -29
- package/dist/utils.test.d.ts +1 -0
- package/dist/virtual/index.d.ts +1 -0
- package/dist/virtual/list.d.ts +53 -0
- package/package.json +19 -16
- package/dist/core/app.d.ts +0 -24
- package/dist/core/env.d.ts +0 -3
- package/dist/core/hooks.d.ts +0 -70
- package/dist/core/logger.d.ts +0 -42
- package/dist/core/logger.test.d.ts +0 -0
- package/dist/core/markup.d.ts +0 -82
- package/dist/core/markup.test.d.ts +0 -0
- package/dist/core/nodes/_markup.d.ts +0 -36
- package/dist/core/nodes/dynamic.d.ts +0 -22
- package/dist/core/nodes/element.d.ts +0 -27
- package/dist/core/nodes/portal.d.ts +0 -18
- package/dist/core/nodes/repeat.d.ts +0 -27
- package/dist/core/nodes/view.d.ts +0 -25
- package/dist/core/views/default-crash-view.d.ts +0 -25
- package/dist/core/views/for.d.ts +0 -21
- package/dist/core/views/fragment.d.ts +0 -7
- package/dist/core/views/portal.d.ts +0 -16
- package/dist/core/views/show.d.ts +0 -25
- package/dist/fragment-BahD_BJA.js +0 -7
- package/dist/fragment-BahD_BJA.js.map +0 -1
- package/dist/i18n/index.d.ts +0 -134
- package/dist/i18n.js +0 -309
- package/dist/i18n.js.map +0 -1
- package/dist/index-DRJlxs-Q.js +0 -535
- package/dist/index-DRJlxs-Q.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger-Aqi9m1CF.js +0 -565
- package/dist/logger-Aqi9m1CF.js.map +0 -1
- package/dist/markup-8jNhoqDe.js +0 -1089
- package/dist/markup-8jNhoqDe.js.map +0 -1
- package/dist/router/hooks.d.ts +0 -2
- package/dist/router/router.utils.d.ts +0 -93
- package/dist/typeChecking-5kmX0ulW.js +0 -65
- package/dist/typeChecking-5kmX0ulW.js.map +0 -1
- package/dist/typeChecking.d.ts +0 -95
- package/docs/buildless.md +0 -132
- package/docs/components.md +0 -238
- package/docs/hooks.md +0 -356
- package/docs/http.md +0 -178
- package/docs/i18n.md +0 -220
- package/docs/index.md +0 -10
- package/docs/markup.md +0 -136
- package/docs/mixins.md +0 -176
- package/docs/ref.md +0 -77
- package/docs/router.md +0 -281
- package/docs/setup.md +0 -137
- package/docs/signals.md +0 -262
- package/docs/stores.md +0 -113
- package/docs/views.md +0 -356
- package/notes/atomic.md +0 -452
- package/notes/elimination.md +0 -33
- package/notes/observable.md +0 -180
- package/notes/scratch.md +0 -565
- package/notes/splitting.md +0 -5
- package/notes/views.md +0 -195
- package/vite.config.js +0 -22
- /package/dist/core/{hooks.test.d.ts → markup/html.test.d.ts} +0 -0
- /package/dist/core/{ref.test.d.ts → markup/utils.test.d.ts} +0 -0
- /package/dist/router/{router.utils.test.d.ts → matcher.test.d.ts} +0 -0
- /package/dist/{typeChecking.test.d.ts → router/router.test.d.ts} +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { n as e, r as t, s as n, u as r } from "./signals-CMJPGr_M.js";
|
|
2
|
+
//#region src/translate/index.ts
|
|
3
|
+
var i = Symbol("Dolla.Translator");
|
|
4
|
+
function a(e) {
|
|
5
|
+
return async function(t) {
|
|
6
|
+
let n = s(e);
|
|
7
|
+
t[i] = n, await n.setLocale(e.locale);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function o(e) {
|
|
11
|
+
if (!e[i]) throw Error("Translate plugin isn't loaded.");
|
|
12
|
+
return e[i];
|
|
13
|
+
}
|
|
14
|
+
function s(r) {
|
|
15
|
+
let i = /* @__PURE__ */ new Map();
|
|
16
|
+
if (i.set("number", (e, t, n) => new Intl.NumberFormat(e, n).format(Number(t))), i.set("datetime", (e, t, n) => new Intl.DateTimeFormat(e, n).format(new Date(t))), i.set("list", (e, t, n) => new Intl.ListFormat(e, n).format(t)), r.formatters) for (let e in r.formatters) i.set(e, r.formatters[e]);
|
|
17
|
+
let a, [o, s] = t("en"), l = [...Object.keys(r.translations)];
|
|
18
|
+
async function u(e) {
|
|
19
|
+
let t;
|
|
20
|
+
if (e === void 0) {
|
|
21
|
+
let e = [];
|
|
22
|
+
if (typeof navigator < "u") {
|
|
23
|
+
let t = navigator;
|
|
24
|
+
t.languages?.length > 0 ? e.push(...t.languages) : t.language ? e.push(t.language) : t.browserLanguage ? e.push(t.browserLanguage) : t.userLanguage && e.push(t.userLanguage);
|
|
25
|
+
}
|
|
26
|
+
for (let n of e) if (n in r.translations) {
|
|
27
|
+
t = n;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
} else e in r.translations && (t = e);
|
|
31
|
+
if (t == null) {
|
|
32
|
+
let e = Object.keys(r.translations).at(0);
|
|
33
|
+
e && (t = e);
|
|
34
|
+
}
|
|
35
|
+
if (!t || !(t in r.translations)) throw Error(`Locale '${e}' has no translation.`);
|
|
36
|
+
a = await c(t, i, r.translations[t]), s(t);
|
|
37
|
+
}
|
|
38
|
+
function d(t, n) {
|
|
39
|
+
return e(() => (o(), a?.(t, n) ?? t));
|
|
40
|
+
}
|
|
41
|
+
function f(t, r, a) {
|
|
42
|
+
let s = i.get(t);
|
|
43
|
+
if (!s) throw Error(`Unknown format: ${t}`);
|
|
44
|
+
return e(() => s(o(), n(r), a ?? {}));
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
supportedLocales: l,
|
|
48
|
+
currentLocale: o,
|
|
49
|
+
setLocale: u,
|
|
50
|
+
t: d,
|
|
51
|
+
format: f
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function c(e, t, i) {
|
|
55
|
+
let a = l(r(i) ? await i() : i), o = new Map(a);
|
|
56
|
+
return function(r, i) {
|
|
57
|
+
if (i && (i.context != null && (r += "_" + i.context), i.count != null)) if (i.ordinal) {
|
|
58
|
+
let t = `${r}_ordinal_(=${i.count})`;
|
|
59
|
+
o.has(t) ? r = t : r += "_ordinal_" + new Intl.PluralRules(e, { type: "ordinal" }).select(n(i.count));
|
|
60
|
+
} else {
|
|
61
|
+
let t = `${r}_(=${i.count})`;
|
|
62
|
+
o.has(t) ? r = t : r += "_" + new Intl.PluralRules(e).select(n(i.count));
|
|
63
|
+
}
|
|
64
|
+
let a = o.get(r);
|
|
65
|
+
if (!a) return r;
|
|
66
|
+
let s = "";
|
|
67
|
+
for (let n = 0; n < a.length; n++) s += a[n](i, t, e);
|
|
68
|
+
return s;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function l(e, t = []) {
|
|
72
|
+
let n = [];
|
|
73
|
+
for (let r in e) switch (typeof e[r]) {
|
|
74
|
+
case "string":
|
|
75
|
+
n.push([[...t, r].join("."), u(e[r])]);
|
|
76
|
+
break;
|
|
77
|
+
case "object":
|
|
78
|
+
n.push(...l(e[r], [...t, r]));
|
|
79
|
+
break;
|
|
80
|
+
default: throw Error(`Expected to find a string or object at ${[...t, r].join(".")}. Got: ${typeof e[r]}`);
|
|
81
|
+
}
|
|
82
|
+
return n;
|
|
83
|
+
}
|
|
84
|
+
function u(e) {
|
|
85
|
+
let t = e.split(/(\{\{.*?\}\})/g), r = [];
|
|
86
|
+
for (let e = 0; e < t.length; e++) {
|
|
87
|
+
let i = t[e];
|
|
88
|
+
if (i) if (i.startsWith("{{") && i.endsWith("}}")) {
|
|
89
|
+
let e = i.slice(2, -2).trim().split("|").map((e) => e.trim()), t = e[0], a = [];
|
|
90
|
+
for (let t = 1; t < e.length; t++) {
|
|
91
|
+
let n = e[t], r = n.match(/^([a-zA-Z0-9_]+)(?:\((.*)\))?$/);
|
|
92
|
+
if (r) {
|
|
93
|
+
let e = r[1], t = r[2], n = {};
|
|
94
|
+
if (t) {
|
|
95
|
+
let e = t.split(",");
|
|
96
|
+
for (let t = 0; t < e.length; t++) {
|
|
97
|
+
let r = e[t], i = r.indexOf(":");
|
|
98
|
+
i > -1 && (n[r.slice(0, i).trim()] = r.slice(i + 1).trim());
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
a.push({
|
|
102
|
+
name: e,
|
|
103
|
+
options: n
|
|
104
|
+
});
|
|
105
|
+
} else a.push({
|
|
106
|
+
name: n,
|
|
107
|
+
options: {}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
r.push((e, r, i) => {
|
|
111
|
+
let o = e ? n(e[t]) : void 0;
|
|
112
|
+
for (let e = 0; e < a.length; e++) {
|
|
113
|
+
let t = a[e], n = r.get(t.name);
|
|
114
|
+
n && (o = n(i, o, t.options));
|
|
115
|
+
}
|
|
116
|
+
return o == null ? "" : String(o);
|
|
117
|
+
});
|
|
118
|
+
} else r.push(() => i);
|
|
119
|
+
}
|
|
120
|
+
return r;
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { l as compile, a as createTranslatePlugin, o as getTranslate, u as parseTemplate };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=translate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","names":[],"sources":["../src/translate/index.ts"],"sourcesContent":["import { Context } from \"../core/context.js\";\nimport { DollaPlugin } from \"../core/root.js\";\nimport { unwrap, compose, createAtom, type Getter } from \"../core/signals.js\";\nimport { isFunction } from \"../utils.js\";\n\n// ----- Types ----- //\n\n/**\n * A JSON object of translated strings. Values can be string templates or nested objects.\n */\nexport interface LocalizedStrings extends Record<string, string | LocalizedStrings> {}\n\n/**\n * A function that returns an object of localized strings.\n */\nexport type TranslationFetchFn = () => LocalizedStrings | Promise<LocalizedStrings>;\n\nexport type TOptions = {\n /**\n *\n */\n count?: Getter<number> | number;\n\n /**\n *\n */\n context?: Getter<string> | string;\n\n [value: string]: Getter<any> | any;\n};\n\nexport type LookupFn = (selector: string, options?: TOptions) => string;\n\nexport type Formatter = (locale: string, value: any, options: Record<string, any>) => string;\n\ntype BuiltInFormatters = {\n number: [number | bigint, Intl.NumberFormatOptions?];\n datetime: [Date, Intl.DateTimeFormatOptions?];\n list: [Iterable<string>, Intl.ListFormatOptions?];\n};\n\nexport interface Translator {\n /**\n * An array of locale names for all translations the app supports.\n */\n supportedLocales: string[];\n\n /**\n * A Readable containing the currently loaded locale.\n */\n currentLocale: Getter<string>;\n\n /**\n * Updates the locale, fetching any translation files as required.\n * Returns a promise that resolves when the new locale is applied.\n *\n * If `name` is undefined the library will try to match the browser language automatically.\n */\n setLocale(name?: string): Promise<void>;\n\n /**\n * Returns a Readable of the value at `key`.\n\n * @param selector - Key to the translated value.\n * @param options - A map of `{{placeholder}}` names and the values to replace them with.\n *\n * @example\n * const value = t(\"your.key.here\", { count: 5 });\n */\n t(selector: string, options?: TOptions): Getter<string>;\n\n format<K extends keyof BuiltInFormatters, V extends BuiltInFormatters[K][0], O extends BuiltInFormatters[K][1]>(\n name: K,\n value: Getter<V> | V,\n options?: O,\n ): Getter<string>;\n\n format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;\n}\n\nexport interface TranslatorOptions {\n translations: Record<string, LocalizedStrings | TranslationFetchFn>;\n\n /**\n * Default locale to load on startup. The translator will try to match the user's browser language if left undefined.\n */\n locale?: string;\n\n formatters?: Record<string, Formatter>;\n}\n\nconst TRANSLATE = Symbol(\"Dolla.Translator\");\n\nexport function createTranslatePlugin(options: TranslatorOptions): DollaPlugin {\n return async function (context) {\n const translator = createTranslator(options);\n context[TRANSLATE] = translator;\n await translator.setLocale(options.locale);\n };\n}\n\nexport function getTranslate(context: Context): Translator {\n if (!context[TRANSLATE]) throw new Error(\"Translate plugin isn't loaded.\");\n return context[TRANSLATE];\n}\n\n// ----- Code ----- //\n\nfunction createTranslator(options: TranslatorOptions): Translator {\n const formatters = new Map<string, Formatter>();\n\n formatters.set(\"number\", (locale, value, options) => {\n return new Intl.NumberFormat(locale, options).format(Number(value));\n });\n formatters.set(\"datetime\", (locale, value, options) => {\n return new Intl.DateTimeFormat(locale, options).format(new Date(value));\n });\n formatters.set(\"list\", (locale, value, options) => {\n return new Intl.ListFormat(locale, options).format(value);\n });\n\n if (options.formatters) {\n for (const key in options.formatters) {\n formatters.set(key, options.formatters[key]);\n }\n }\n\n let lookup: LookupFn | undefined;\n\n const [currentLocale, setCurrentLocale] = createAtom(\"en\");\n const supportedLocales = [...Object.keys(options.translations)];\n\n /**\n * Loads translation for the locale.\n */\n async function setLocale(name?: string) {\n let locale!: string;\n\n if (name === undefined) {\n let names = [];\n\n if (typeof navigator !== \"undefined\") {\n const nav = navigator as any;\n\n if (nav.languages?.length > 0) {\n names.push(...nav.languages);\n } else if (nav.language) {\n names.push(nav.language);\n } else if (nav.browserLanguage) {\n names.push(nav.browserLanguage);\n } else if (nav.userLanguage) {\n names.push(nav.userLanguage);\n }\n }\n\n for (const name of names) {\n if (name in options.translations) {\n // Found a matching language.\n locale = name;\n break;\n }\n }\n } else {\n // Tag is the actual tag to set.\n if (name in options.translations) {\n locale = name;\n }\n }\n\n if (locale == null) {\n const firstLanguage = Object.keys(options.translations).at(0);\n if (firstLanguage) {\n locale = firstLanguage;\n }\n }\n\n if (!locale || !(locale in options.translations)) {\n throw new Error(`Locale '${name}' has no translation.`);\n }\n\n lookup = await createLookup(locale, formatters, options.translations[locale]);\n\n // Update locale string after init so t() signals will update.\n setCurrentLocale(locale);\n }\n\n function t(selector: string, options?: TOptions): Getter<string> {\n return compose(() => {\n currentLocale(); // track locale\n return lookup?.(selector, options) ?? selector;\n });\n }\n\n function format<\n K extends keyof BuiltInFormatters,\n V extends BuiltInFormatters[K][0],\n O extends BuiltInFormatters[K][1],\n >(name: K, value: Getter<V> | V, options?: O): Getter<string>;\n\n function format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;\n\n function format(name: string, value: unknown, options?: Record<string, any>): Getter<string> {\n const callback = formatters.get(name);\n if (!callback) {\n throw new Error(`Unknown format: ${name}`);\n }\n\n return compose(() => callback(currentLocale(), unwrap(value), options ?? {}));\n }\n\n return {\n supportedLocales,\n currentLocale,\n setLocale,\n t,\n format,\n };\n}\n\n/**\n * Loads the translation and produces an efficient lookup function.\n */\nasync function createLookup(\n locale: string,\n formatters: Map<string, Formatter>,\n translation: TranslationFetchFn | LocalizedStrings,\n) {\n const strings = isFunction(translation) ? await translation() : translation;\n const entries = compile(strings);\n const templates = new Map(entries);\n\n /**\n * Looks up the template and produces the output. Any reactive values in `options` are tracked when used.\n */\n return function lookup(selector: string, options?: TOptions): string {\n if (options) {\n // Handle count (pluralization) and context. Keys become \"key_context_pluralization\".\n if (options.context != null) {\n selector += \"_\" + options.context;\n }\n if (options.count != null) {\n if (options.ordinal) {\n // Try to match the exact number key if there is one (e.g. \"myExampleKey_ordinal_(=2)\" when count is 2).\n const exact = `${selector}_ordinal_(=${options.count})`;\n if (templates.has(exact)) {\n selector = exact;\n } else {\n selector += \"_ordinal_\" + new Intl.PluralRules(locale, { type: \"ordinal\" }).select(unwrap(options.count));\n }\n } else {\n // Try to match the exact number key if there is one (e.g. \"myExampleKey_(=2)\" when count is 2).\n const exact = `${selector}_(=${options.count})`;\n if (templates.has(exact)) {\n selector = exact;\n } else {\n selector += \"_\" + new Intl.PluralRules(locale).select(unwrap(options.count));\n }\n }\n }\n }\n\n const template = templates.get(selector);\n if (!template) return selector;\n\n let output = \"\";\n\n for (let i = 0; i < template.length; i++) {\n output += template[i](options, formatters, locale);\n }\n\n return output;\n };\n}\n\n/**\n * Compiles an object of translated strings into a set of function templates.\n */\nexport function compile(strings: { [key: string]: any }, path: string[] = []): [string, CompiledTemplate][] {\n const entries: [string, CompiledTemplate][] = [];\n\n for (const key in strings) {\n switch (typeof strings[key]) {\n case \"string\":\n entries.push([[...path, key].join(\".\"), parseTemplate(strings[key])]);\n break;\n case \"object\":\n entries.push(...compile(strings[key], [...path, key]));\n break;\n default:\n throw new Error(\n `Expected to find a string or object at ${[...path, key].join(\".\")}. Got: ${typeof strings[key]}`,\n );\n }\n }\n\n return entries;\n}\n\nexport type TemplateSegmentFn = (\n options: Record<string, any> | undefined,\n formatters: Map<string, Formatter>,\n locale: string,\n) => string;\n\nexport type CompiledTemplate = TemplateSegmentFn[];\n\n/**\n * Parse a string template into an array of functions that will produce each piece of the output when called.\n */\nexport function parseTemplate(template: string): CompiledTemplate {\n const tokens = template.split(/(\\{\\{.*?\\}\\})/g);\n const segments: TemplateSegmentFn[] = [];\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (!token) continue;\n\n if (token.startsWith(\"{{\") && token.endsWith(\"}}\")) {\n const inner = token.slice(2, -2).trim();\n const parts = inner.split(\"|\").map((p) => p.trim());\n\n const name = parts[0];\n const parsedFormats: { name: string; options: Record<string, string> }[] = [];\n\n // Parse formatters at build-time to prevent string splitting on every render\n for (let j = 1; j < parts.length; j++) {\n const formatStr = parts[j];\n const match = formatStr.match(/^([a-zA-Z0-9_]+)(?:\\((.*)\\))?$/);\n\n if (match) {\n const formatName = match[1];\n const optionsStr = match[2];\n const optsObj: Record<string, string> = {};\n\n if (optionsStr) {\n const pairs = optionsStr.split(\",\");\n for (let k = 0; k < pairs.length; k++) {\n const pair = pairs[k];\n const colonIndex = pair.indexOf(\":\");\n if (colonIndex > -1) {\n optsObj[pair.slice(0, colonIndex).trim()] = pair.slice(colonIndex + 1).trim();\n }\n }\n }\n parsedFormats.push({ name: formatName, options: optsObj });\n } else {\n parsedFormats.push({ name: formatStr, options: {} });\n }\n }\n\n // Push the dynamic closure\n segments.push((options, formatters, locale) => {\n // Evaluate and track the specific option at runtime.\n // This code runs in the t() computed context.\n let value = options ? unwrap(options[name]) : undefined;\n\n for (let k = 0; k < parsedFormats.length; k++) {\n const fmt = parsedFormats[k];\n const formatterFn = formatters.get(fmt.name);\n if (formatterFn) {\n value = formatterFn(locale, value, fmt.options);\n }\n }\n\n return value != null ? String(value) : \"\";\n });\n } else {\n // Push a static closure that just returns the token\n segments.push(() => token);\n }\n }\n\n return segments;\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
import type * as CSS from "csstype";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { ComponentState, Context } from "./core/context.js";
|
|
3
|
+
import type { Markup, MarkupNode } from "./core/markup/types.js";
|
|
4
|
+
import type { Getter } from "./core/signals.js";
|
|
4
5
|
export type Env = "production" | "development";
|
|
5
6
|
/**
|
|
6
7
|
* Represents everything that can be handled as a DOM node.
|
|
7
8
|
* These are all the items considered valid to pass as children to any element.
|
|
8
9
|
*/
|
|
9
|
-
export type Renderable = string | number | Node | Markup | MarkupNode | false | null | undefined |
|
|
10
|
+
export type Renderable = string | number | Node | Markup | MarkupNode | false | null | undefined | void | Getter<any> | Renderable[];
|
|
10
11
|
export interface BaseProps {
|
|
11
12
|
children?: Renderable;
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
export type Store<Options, Value> = (options: Options) => Value;
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
*/
|
|
24
|
-
export type Mixin<E extends Element = Element> = (element: E) => void;
|
|
25
|
-
type MaybeSignal<T> = T | Signal<T> | Signal<T | undefined>;
|
|
26
|
-
type OptionalProperty<T> = MaybeSignal<T>;
|
|
27
|
-
type RequiredProperty<T> = T | Signal<T>;
|
|
14
|
+
export type View<Props = {}, State = Record<string | symbol, any>> = (this: Context<ComponentState & State>, props: Props, context: Context<ComponentState & State>) => Renderable;
|
|
15
|
+
export type Store<Props, Value, State = Record<string | symbol, any>> = (this: Context<ComponentState & State>, props: Props, context: Context<ComponentState & State>) => Value;
|
|
16
|
+
export type MaybeGetter<T> = Getter<T> | T;
|
|
17
|
+
type RequiredProperty<T> = Getter<T> | T;
|
|
18
|
+
type OptionalProperty<T> = Getter<T> | Getter<T | undefined> | T;
|
|
28
19
|
type AutocapitalizeValues = "off" | "on" | "none" | "sentences" | "words" | "characters";
|
|
29
20
|
type ContentEditableValues = true | false | "true" | "false" | "plaintext-only" | "inherit";
|
|
30
21
|
type ClassListValues = string | ClassMap | Array<string | ClassMap | (string | ClassMap)[]>;
|
|
@@ -48,12 +39,6 @@ export interface ElementProps {
|
|
|
48
39
|
* Attaches an event listener to the element (with `addEventListener`).
|
|
49
40
|
*/
|
|
50
41
|
[key: `on:${string}`]: OptionalProperty<EventHandler<Event>>;
|
|
51
|
-
/**
|
|
52
|
-
* HTML attributes to assign to the element.
|
|
53
|
-
*/
|
|
54
|
-
/**
|
|
55
|
-
* Object of event listeners.
|
|
56
|
-
*/
|
|
57
42
|
/**
|
|
58
43
|
* CSS classes to be applied to this element. In addition to the standard space-separated list of class names,
|
|
59
44
|
* this property also supports a class map object with class names as keys and booleans as values.
|
|
@@ -158,7 +143,7 @@ export interface ElementProps {
|
|
|
158
143
|
*
|
|
159
144
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/style
|
|
160
145
|
*/
|
|
161
|
-
style?: string | CSSProperties |
|
|
146
|
+
style?: string | CSSProperties | Getter<string> | Getter<CSSProperties> | Getter<string | CSSProperties> | Getter<string | undefined> | Getter<CSSProperties | undefined> | Getter<string | CSSProperties | undefined>;
|
|
162
147
|
/**
|
|
163
148
|
* Fired when a CSS animation unexpectedly aborts.
|
|
164
149
|
*
|
|
@@ -721,6 +706,10 @@ export interface ElementProps {
|
|
|
721
706
|
onwheel?: OptionalProperty<EventHandler<WheelEvent>>;
|
|
722
707
|
}
|
|
723
708
|
export interface HTMLElementProps extends ElementProps {
|
|
709
|
+
/**
|
|
710
|
+
* Data attribute.
|
|
711
|
+
*/
|
|
712
|
+
[key: `data-${string}`]: OptionalProperty<any>;
|
|
724
713
|
/**
|
|
725
714
|
* Sets the key a user can press to jump to this element.
|
|
726
715
|
*
|
|
@@ -1002,12 +991,6 @@ export interface HTMLElementProps extends ElementProps {
|
|
|
1002
991
|
*/
|
|
1003
992
|
onpaste?: OptionalProperty<EventHandler<ClipboardEvent>>;
|
|
1004
993
|
}
|
|
1005
|
-
export interface SVGElementProps extends ElementProps {
|
|
1006
|
-
/**
|
|
1007
|
-
* A mixin function or an array of mixin functions to be applied to this element.
|
|
1008
|
-
*/
|
|
1009
|
-
mixin?: Mixin<SVGElement> | Mixin<SVGElement>[];
|
|
1010
|
-
}
|
|
1011
994
|
/**
|
|
1012
995
|
* Mapping of event props to event names.
|
|
1013
996
|
*/
|
|
@@ -1279,7 +1262,7 @@ export type CSSProperties = {
|
|
|
1279
1262
|
[K in keyof Styles]: OptionalProperty<Styles[K]>;
|
|
1280
1263
|
};
|
|
1281
1264
|
export interface ClassMap {
|
|
1282
|
-
[className: string]:
|
|
1265
|
+
[className: string]: OptionalProperty<any>;
|
|
1283
1266
|
}
|
|
1284
1267
|
export type EventHandler<E> = (event: E) => void;
|
|
1285
1268
|
export interface PropertiesOf<E extends HTMLElement> extends HTMLElementProps {
|
|
@@ -1289,12 +1272,9 @@ export interface PropertiesOf<E extends HTMLElement> extends HTMLElementProps {
|
|
|
1289
1272
|
children?: any;
|
|
1290
1273
|
/**
|
|
1291
1274
|
* Receives a reference to the DOM node when rendered.
|
|
1275
|
+
* Returns a cleanup function that is called when the node is removed.
|
|
1292
1276
|
*/
|
|
1293
|
-
ref?: ((value: E
|
|
1294
|
-
/**
|
|
1295
|
-
* A mixin function or an array of mixin functions to be applied to this element.
|
|
1296
|
-
*/
|
|
1297
|
-
mixin?: Mixin<E> | Mixin<E>[];
|
|
1277
|
+
ref?: ((value: E) => () => void) | ((value: HTMLElement) => () => void) | ((value: Element) => () => void) | ((value: Node) => () => void);
|
|
1298
1278
|
}
|
|
1299
1279
|
/**
|
|
1300
1280
|
* The following elements are defined based on the WHATWG HTML spec:
|
|
@@ -2171,7 +2151,7 @@ interface HTMLMediaElementProps<T extends HTMLMediaElement> extends HTMLElementP
|
|
|
2171
2151
|
*
|
|
2172
2152
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject
|
|
2173
2153
|
*/
|
|
2174
|
-
srcObject?: MediaStream | MediaSource | Blob | File |
|
|
2154
|
+
srcObject?: MediaStream | MediaSource | Blob | File | Getter<MediaStream> | Getter<MediaStream | undefined> | Getter<MediaSource> | Getter<MediaSource | undefined> | Getter<Blob> | Getter<Blob | undefined> | Getter<File> | Getter<File | undefined>;
|
|
2175
2155
|
/**
|
|
2176
2156
|
* The current audio volume of the media element. Must be a number between 0 and 1.
|
|
2177
2157
|
*
|
|
@@ -2670,7 +2650,7 @@ interface HTMLImageElementProps extends PropertiesOf<HTMLImageElement> {
|
|
|
2670
2650
|
*
|
|
2671
2651
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes
|
|
2672
2652
|
*/
|
|
2673
|
-
sizes?:
|
|
2653
|
+
sizes?: OptionalProperty<string>;
|
|
2674
2654
|
/**
|
|
2675
2655
|
* The image URL.
|
|
2676
2656
|
*
|
|
@@ -3425,4 +3405,6 @@ interface HTMLCanvasElementProps extends PropertiesOf<HTMLCanvasElement> {
|
|
|
3425
3405
|
*/
|
|
3426
3406
|
height?: OptionalProperty<string | number> | OptionalProperty<string> | OptionalProperty<number>;
|
|
3427
3407
|
}
|
|
3408
|
+
export interface IntrinsicElements {
|
|
3409
|
+
}
|
|
3428
3410
|
export {};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,46 +1,58 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare function getUniqueId(): string;
|
|
3
|
-
export declare function getIntegerId(): number;
|
|
1
|
+
export declare function uniqueId(): string;
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Returns a new object without the specified keys.
|
|
4
|
+
* If called without object, returns a function that takes an object
|
|
5
|
+
* and returns a version with the original keys omitted.
|
|
6
|
+
*
|
|
7
|
+
* @param keys - An array of keys to omit.
|
|
8
|
+
* @param object - An object to clone without the omitted keys.
|
|
7
9
|
*/
|
|
8
|
-
export declare function
|
|
10
|
+
export declare function omit<O extends Record<any, any>>(keys: (keyof O)[], object: O): Record<any, any>;
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Throws a TypeError unless `condition` is truthy.
|
|
13
|
+
*
|
|
14
|
+
* @param value - Value whose truthiness is in question.
|
|
15
|
+
* @param errorMessage - Optional message for the thrown TypeError.
|
|
11
16
|
*/
|
|
12
|
-
export declare function
|
|
17
|
+
export declare function assert<T = any>(value: T, errorMessage: string): asserts value is NonNullable<T>;
|
|
13
18
|
/**
|
|
14
|
-
*
|
|
19
|
+
* Returns true if `value` is an array.
|
|
15
20
|
*/
|
|
16
|
-
export declare function
|
|
21
|
+
export declare function isArray(value: unknown): value is Array<unknown>;
|
|
17
22
|
/**
|
|
18
|
-
*
|
|
23
|
+
* Returns true when `value` is an array and `check` returns true for every item.
|
|
24
|
+
*
|
|
25
|
+
* @param check - Function to check items against.
|
|
26
|
+
* @param value - A possible array.
|
|
19
27
|
*/
|
|
20
|
-
export declare function
|
|
28
|
+
export declare function isArrayOf<T>(check: (item: unknown) => boolean, value: unknown): value is T[];
|
|
29
|
+
export declare function isArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];
|
|
21
30
|
/**
|
|
22
|
-
* Returns
|
|
23
|
-
* If called without object, returns a function that takes an object
|
|
24
|
-
* and returns a version with the original keys omitted.
|
|
25
|
-
*
|
|
26
|
-
* @param keys - An array of keys to omit.
|
|
27
|
-
* @param object - An object to clone without the omitted keys.
|
|
31
|
+
* Returns true if `value` is a string.
|
|
28
32
|
*/
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function toArray<T>(value: T | T[]): T[];
|
|
31
|
-
export declare function toCamelCase(s: string): string;
|
|
33
|
+
export declare function isString(value: unknown): value is string;
|
|
32
34
|
/**
|
|
33
|
-
*
|
|
35
|
+
* Returns true if `value` is a function (but not a class).
|
|
34
36
|
*/
|
|
35
|
-
export declare function
|
|
37
|
+
export declare function isFunction<T = (...args: unknown[]) => unknown>(value: unknown): value is T;
|
|
38
|
+
export declare function isClass(value: unknown): boolean;
|
|
36
39
|
/**
|
|
37
|
-
*
|
|
40
|
+
* Returns true if `value` is a number.
|
|
38
41
|
*/
|
|
39
|
-
export declare function
|
|
40
|
-
export type MatcherFunction = (value: string) => boolean;
|
|
42
|
+
export declare function isNumber(value: unknown): value is number;
|
|
41
43
|
/**
|
|
42
|
-
*
|
|
44
|
+
* Returns `true` if `value` is an instance of `constructor`.
|
|
43
45
|
*
|
|
44
|
-
* @param
|
|
46
|
+
* @param constructor - The constructor `value` must be an instance of.
|
|
47
|
+
* @param value - A value that may be an instance of `constructor`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isInstanceOf<T extends Function>(constructor: T, value: unknown): value is T;
|
|
50
|
+
export declare function isInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;
|
|
51
|
+
/**
|
|
52
|
+
* Returns true if `value` is a JavaScript Promise.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isPromise<T = unknown>(value: unknown): value is Promise<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Returns true if `value` is a plain JavaScript object.
|
|
45
57
|
*/
|
|
46
|
-
export declare function
|
|
58
|
+
export declare function isObject<T = Record<string | number | symbol, unknown>>(value: unknown): value is T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createVirtualList } from "./list";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type Getter } from "../core/signals.js";
|
|
2
|
+
import { View } from "../types.js";
|
|
3
|
+
export interface VirtualListAPI<T> {
|
|
4
|
+
scrollToBottom: (smooth?: boolean) => void;
|
|
5
|
+
scrollToTop: (smooth?: boolean) => void;
|
|
6
|
+
scrollToIndex: (index: number, options?: {
|
|
7
|
+
smooth?: boolean;
|
|
8
|
+
align?: "start" | "center" | "end";
|
|
9
|
+
}) => void;
|
|
10
|
+
scrollToItem: (item: T, options?: {
|
|
11
|
+
smooth?: boolean;
|
|
12
|
+
align?: "start" | "center" | "end";
|
|
13
|
+
}) => void;
|
|
14
|
+
isAtBottom: Getter<boolean>;
|
|
15
|
+
}
|
|
16
|
+
export interface VirtualListContext {
|
|
17
|
+
isEntering: Getter<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export interface VirtualListOptions<T> {
|
|
20
|
+
items: Getter<T[]>;
|
|
21
|
+
/** A stable identifier for each item, crucial for detecting changes accurately */
|
|
22
|
+
keyFn: (item: T) => string | number;
|
|
23
|
+
bottomUp?: boolean;
|
|
24
|
+
enterAnimationMs?: number;
|
|
25
|
+
/** Configuration for the virtual pool */
|
|
26
|
+
estimatedItemHeight?: number;
|
|
27
|
+
poolSize?: number;
|
|
28
|
+
/** Infinite scroll callbacks */
|
|
29
|
+
onTopReached?: () => void;
|
|
30
|
+
onBottomReached?: () => void;
|
|
31
|
+
threshold?: number;
|
|
32
|
+
render: (item: Getter<T>, index: Getter<number>, context: VirtualListContext) => any;
|
|
33
|
+
renderEmpty?: () => any;
|
|
34
|
+
isSticky?: (item: T) => boolean;
|
|
35
|
+
renderSticky?: (item: Getter<T>) => any;
|
|
36
|
+
}
|
|
37
|
+
export declare function createVirtualList<T>(props: VirtualListOptions<T>): [View, VirtualListAPI<T>];
|
|
38
|
+
export declare function createOffsetEngine(defaultAssumption: number): {
|
|
39
|
+
averageHeight: Getter<number>;
|
|
40
|
+
getTotalHeight: (totalItems: number) => number;
|
|
41
|
+
getOffset: (index: number, avg: number) => number;
|
|
42
|
+
findIndexAtScroll: (scrollPos: number, totalItems: number, avg: number) => number;
|
|
43
|
+
findSticky: (scrollPos: number, indices: number[], avg: number) => {
|
|
44
|
+
activeIdx: number;
|
|
45
|
+
nextIdx: number;
|
|
46
|
+
};
|
|
47
|
+
updateHeights: (entries: {
|
|
48
|
+
index: number;
|
|
49
|
+
height: number;
|
|
50
|
+
}[], avg: number) => boolean;
|
|
51
|
+
clearCache: () => void;
|
|
52
|
+
getItemHeight: (index: number) => number | undefined;
|
|
53
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manyducks.co/dolla",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A fast, batteries-included JavaScript framework with a React-
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "A fast, batteries-included JavaScript framework with a React-inspired API and the power of signals.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/core/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"web app",
|
|
22
22
|
"front end framework",
|
|
23
23
|
"functional",
|
|
24
|
-
"reactive state"
|
|
24
|
+
"reactive state",
|
|
25
|
+
"signals"
|
|
25
26
|
],
|
|
26
27
|
"author": "tony@manyducks.co",
|
|
27
28
|
"license": "MIT",
|
|
@@ -34,14 +35,14 @@
|
|
|
34
35
|
"import": "./dist/router.js",
|
|
35
36
|
"types": "./dist/router/index.d.ts"
|
|
36
37
|
},
|
|
38
|
+
"./translate": {
|
|
39
|
+
"import": "./dist/translate.js",
|
|
40
|
+
"types": "./dist/translate/index.d.ts"
|
|
41
|
+
},
|
|
37
42
|
"./http": {
|
|
38
43
|
"import": "./dist/http.js",
|
|
39
44
|
"types": "./dist/http/index.d.ts"
|
|
40
45
|
},
|
|
41
|
-
"./i18n": {
|
|
42
|
-
"import": "./dist/i18n.js",
|
|
43
|
-
"types": "./dist/i18n/index.d.ts"
|
|
44
|
-
},
|
|
45
46
|
"./jsx-runtime": {
|
|
46
47
|
"import": "./dist/jsx-runtime.js",
|
|
47
48
|
"types": "./jsx-runtime.d.ts"
|
|
@@ -51,15 +52,17 @@
|
|
|
51
52
|
"types": "./jsx-dev-runtime.d.ts"
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
55
|
+
"files": [
|
|
56
|
+
"dist",
|
|
57
|
+
"*.d.ts"
|
|
58
|
+
],
|
|
57
59
|
"devDependencies": {
|
|
58
|
-
"@types/node": "^
|
|
59
|
-
"csstype": "^3.
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
60
|
+
"@types/node": "^25.6.0",
|
|
61
|
+
"csstype": "^3.2.3",
|
|
62
|
+
"jsdom": "^29.0.2",
|
|
63
|
+
"prettier": "^3.8.3",
|
|
64
|
+
"typescript": "^6.0.3",
|
|
65
|
+
"vite": "^8.0.10",
|
|
66
|
+
"vitest": "^4.1.5"
|
|
64
67
|
}
|
|
65
68
|
}
|
package/dist/core/app.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Router, RouterOptions } from "../router/router";
|
|
2
|
-
import { View } from "../types";
|
|
3
|
-
import { Context } from "./context";
|
|
4
|
-
import { LoggerCrashProps } from "./logger";
|
|
5
|
-
interface AppOptions {
|
|
6
|
-
view?: View<{}>;
|
|
7
|
-
router?: Router;
|
|
8
|
-
context?: Context;
|
|
9
|
-
}
|
|
10
|
-
declare class App {
|
|
11
|
-
#private;
|
|
12
|
-
get context(): Context;
|
|
13
|
-
constructor(options: AppOptions);
|
|
14
|
-
setCrashView(view: View<LoggerCrashProps>): this;
|
|
15
|
-
mount(element: string | Element): Promise<void>;
|
|
16
|
-
unmount(): Promise<void>;
|
|
17
|
-
}
|
|
18
|
-
export interface CreateAppOptions {
|
|
19
|
-
context?: Context;
|
|
20
|
-
}
|
|
21
|
-
export declare function createApp(view: View<{}>, options?: CreateAppOptions): App;
|
|
22
|
-
export declare function createApp(routerOptions: RouterOptions, options?: CreateAppOptions): App;
|
|
23
|
-
export declare function createApp(router: Router, options?: CreateAppOptions): App;
|
|
24
|
-
export {};
|
package/dist/core/env.d.ts
DELETED
package/dist/core/hooks.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { type Context, type Ref, type Store } from "../core";
|
|
2
|
-
import { type EffectFn, type MaybeSignal, type Setter, type Signal, type SignalOptions } from "../core/signals";
|
|
3
|
-
/**
|
|
4
|
-
* Returns the Context object of the `View`, `Store` or `Mixin` this hook is called in.
|
|
5
|
-
*
|
|
6
|
-
* @param name - If passed, the context will be renamed. Context takes the name of the component function by default.
|
|
7
|
-
*/
|
|
8
|
-
export declare function useContext(name?: MaybeSignal<string>): Context;
|
|
9
|
-
/**
|
|
10
|
-
* Returns the nearest instance of a Store provided to this context.
|
|
11
|
-
*/
|
|
12
|
-
export declare function useStore<T>(store: Store<any, T>): T;
|
|
13
|
-
/**
|
|
14
|
-
* Adds a store to this context and returns the store instance.
|
|
15
|
-
*/
|
|
16
|
-
export declare function useStoreProvider<T, O>(store: Store<O, T>, options?: O): T;
|
|
17
|
-
/**
|
|
18
|
-
* Schedules `callback` to run just after the component is mounted.
|
|
19
|
-
* If `callback` returns a function, that function will run when the context is unmounted.
|
|
20
|
-
*/
|
|
21
|
-
export declare function useMount(callback: () => void | (() => void)): void;
|
|
22
|
-
/**
|
|
23
|
-
* Schedules `callback` to run when the context is unmounted.
|
|
24
|
-
*/
|
|
25
|
-
export declare function useUnmount(callback: () => void): void;
|
|
26
|
-
/**
|
|
27
|
-
* Creates a new read-only Signal. Returns bound Getter and Setter functions.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* const [$count, setCount] = useSignal(5);
|
|
31
|
-
* $count(); // 5
|
|
32
|
-
* setCount(6);
|
|
33
|
-
* setCount((current) => current + 1);
|
|
34
|
-
* $count(); // 7
|
|
35
|
-
*/
|
|
36
|
-
export declare function useSignal<T>(value: T, options?: SignalOptions<T>): [Signal<T>, Setter<T>];
|
|
37
|
-
export declare function useSignal<T>(value: undefined, options: SignalOptions<T>): [Signal<T | undefined>, Setter<T | undefined>];
|
|
38
|
-
export declare function useSignal<T>(): [Signal<T | undefined>, Setter<T | undefined>];
|
|
39
|
-
export declare function useMemo<T>(compute: (current?: T) => MaybeSignal<T>, deps?: Signal<any>[], options?: SignalOptions<T>): Signal<T>;
|
|
40
|
-
/**
|
|
41
|
-
* Takes the current state and a dispatched action. Returns a new state based on the action.
|
|
42
|
-
* Typically the body of this function will be a large switch statement.
|
|
43
|
-
*/
|
|
44
|
-
export type Reducer<State, Action> = (state: State, action: Action) => State;
|
|
45
|
-
/**
|
|
46
|
-
* Dispatches an action to this reducer, causing the state to update.
|
|
47
|
-
*/
|
|
48
|
-
export type Dispatcher<Action> = (action: Action) => void;
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
*/
|
|
52
|
-
export declare function useReducer<State, Action>(reducer: Reducer<State, Action>, initialState: State): [Signal<State>, Dispatcher<Action>];
|
|
53
|
-
/**
|
|
54
|
-
* Creates an effect bound to the current context.
|
|
55
|
-
* The `fn` is called when the component is mounted, then again each time the dependencies are updated until the component is unmounted.
|
|
56
|
-
*/
|
|
57
|
-
export declare function useEffect(fn: EffectFn, deps?: Signal<any>[]): void;
|
|
58
|
-
/**
|
|
59
|
-
* A hybrid Ref which is both a function ref and a React-style object ref with a `current` property.
|
|
60
|
-
* Both the `current` property and the function syntax access the same value.
|
|
61
|
-
*/
|
|
62
|
-
export interface HybridRef<T> extends Ref<T> {
|
|
63
|
-
current: T;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Creates a Ref. Useful for getting references to DOM nodes.
|
|
67
|
-
*
|
|
68
|
-
* @deprecated use ref()
|
|
69
|
-
*/
|
|
70
|
-
export declare function useRef<T>(initialValue?: T): HybridRef<T>;
|
package/dist/core/logger.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { Env } from "../types.js";
|
|
2
|
-
import { type MaybeSignal } from "./signals.js";
|
|
3
|
-
export interface LogLevels {
|
|
4
|
-
info: boolean | Env;
|
|
5
|
-
log: boolean | Env;
|
|
6
|
-
warn: boolean | Env;
|
|
7
|
-
error: boolean | Env;
|
|
8
|
-
}
|
|
9
|
-
export interface Logger {
|
|
10
|
-
info(...args: any[]): void;
|
|
11
|
-
log(...args: any[]): void;
|
|
12
|
-
warn(...args: any[]): void;
|
|
13
|
-
error(...args: any[]): void;
|
|
14
|
-
crash(error: Error): Error;
|
|
15
|
-
}
|
|
16
|
-
export interface LoggerOptions {
|
|
17
|
-
/**
|
|
18
|
-
* Tag value to print with logs.
|
|
19
|
-
*/
|
|
20
|
-
tag?: string;
|
|
21
|
-
/**
|
|
22
|
-
* Label for tag value. Will be printed without a label if not specified.
|
|
23
|
-
*/
|
|
24
|
-
tagName?: string;
|
|
25
|
-
/**
|
|
26
|
-
* Console object to use for logging (mostly for testing). Uses window.console by default.
|
|
27
|
-
*/
|
|
28
|
-
console?: any;
|
|
29
|
-
}
|
|
30
|
-
export interface LoggerCrashProps {
|
|
31
|
-
error: Error;
|
|
32
|
-
loggerName: string;
|
|
33
|
-
tag?: string;
|
|
34
|
-
tagName?: string;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Listen for logged crashes.
|
|
38
|
-
*/
|
|
39
|
-
export declare function onLoggerCrash(listener: (context: LoggerCrashProps) => void): () => void;
|
|
40
|
-
export declare function createLogger(name: MaybeSignal<string>, options?: LoggerOptions): Logger;
|
|
41
|
-
export declare function setLogFilter(filter: string | RegExp): void;
|
|
42
|
-
export declare function setLogLevels(options: Partial<LogLevels>): void;
|
|
File without changes
|