alepha 0.20.3 → 0.20.5
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/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +14 -14
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +6 -1
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +20 -4
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +6 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +5032 -134
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +58 -10
- package/dist/api/users/index.js.map +1 -1
- package/dist/bin/index.js +0 -0
- package/dist/bucket/index.d.ts +77 -107
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +148 -4
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +7 -1
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +26 -0
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +11 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +11 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cli/config/index.d.ts +7 -5
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -3
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +419 -12
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +22 -511
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +4 -8
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +13 -15
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +10 -13
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +18 -15
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +10 -13
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +16 -13
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +1 -1
- package/dist/core/index.browser.js +27 -3
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -3
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -3
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/datetime/index.d.ts +69 -10
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +135 -13
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/smtp/index.js +10636 -2
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +8085 -4
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +33554 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +30 -2
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +35 -12
- package/dist/lock/core/index.js.map +1 -1
- package/dist/mcp/index.d.ts +238 -31
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +198 -71
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +1 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +4 -3
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +4877 -9
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +4 -3
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +608 -1
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/react/core/index.d.ts +102 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +65 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +6 -0
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +7 -7
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +7 -1
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +6 -0
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/router/index.browser.js +20 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +36 -4
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +20 -2
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/chunk-6Ep1yQYe.js +16 -0
- package/dist/react/testing/index.d.ts +411 -1
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +12293 -13
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +195 -1
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +61 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +84 -3
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +390 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +390 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.d.ts +325 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1361 -2
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1054 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1223 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/core/index.browser.js +10 -3
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +28 -5
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4374 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +3 -4
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/websocket/index.browser.js +11 -5
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +3 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +21 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +416 -8
- package/src/api/parameters/services/ParameterProvider.ts +21 -4
- package/src/api/users/__tests__/SessionService.spec.ts +99 -0
- package/src/api/users/__tests__/UserJobs.spec.ts +67 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +15 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/jobs/UserJobs.ts +44 -17
- package/src/api/users/providers/RealmProvider.ts +4 -0
- package/src/api/users/services/SessionService.ts +27 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +74 -0
- package/src/bucket/index.ts +19 -2
- package/src/bucket/primitives/$bucket.ts +9 -1
- package/src/bucket/providers/CloudflareR2Provider.ts +2 -137
- package/src/bucket/providers/NodeS3BucketProvider.ts +218 -0
- package/src/cache/core/index.ts +29 -0
- package/src/cache/core/primitives/$cache.ts +14 -1
- package/src/cli/config/defineConfig.ts +13 -15
- package/src/cli/core/__tests__/init.spec.ts +6 -7
- package/src/cli/core/services/ProjectScaffolder.ts +18 -14
- package/src/cli/core/tasks/BuildCloudflareTask.ts +5 -0
- package/src/cli/core/templates/agentMd.ts +2 -10
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +3 -3
- package/src/cli/devtools/index.ts +12 -26
- package/src/cli/platform/index.ts +15 -24
- package/src/cli/vendor/atoms/vendorOptions.ts +1 -1
- package/src/cli/vendor/index.ts +14 -23
- package/src/core/Alepha.ts +11 -1
- package/src/core/helpers/ref.ts +18 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/providers/SchemaValidator.ts +9 -1
- package/src/core/providers/TypeProvider.ts +1 -2
- package/src/datetime/REFACTORING.md +118 -0
- package/src/datetime/providers/DateTimeProvider.ts +203 -24
- package/src/lock/core/index.ts +31 -0
- package/src/lock/core/primitives/$lock.ts +14 -1
- package/src/mcp/__tests__/jsonrpc.spec.ts +1 -1
- package/src/mcp/helpers/jsonrpc.ts +26 -1
- package/src/mcp/index.ts +10 -5
- package/src/mcp/interfaces/McpTypes.ts +83 -6
- package/src/mcp/primitives/$prompt.ts +18 -1
- package/src/mcp/primitives/$resource.ts +18 -1
- package/src/mcp/primitives/$tool.ts +83 -7
- package/src/mcp/providers/McpServerProvider.ts +74 -16
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +226 -0
- package/src/orm/REFACTORING.md +330 -0
- package/src/orm/core/primitives/$transactional.ts +11 -0
- package/src/orm/core/schemas/updateSchema.ts +1 -1
- package/src/orm/core/services/PgRelationManager.ts +4 -2
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +86 -0
- package/src/react/core/hooks/useQuery.ts +153 -0
- package/src/react/core/index.ts +1 -0
- package/src/react/form/services/FormModel.ts +15 -6
- package/src/react/form/services/parseField.ts +8 -0
- package/src/react/i18n/providers/I18nProvider.ts +8 -2
- package/src/react/router/__tests__/$page.spec.tsx +0 -16
- package/src/react/router/__tests__/ssr.spec.tsx +339 -0
- package/src/react/router/primitives/$page.ts +28 -4
- package/src/react/router/providers/ReactPageProvider.ts +27 -9
- package/src/react/ui/atoms/uiThemeListAtom.ts +36 -0
- package/src/react/ui/index.ts +6 -0
- package/src/react/ui/services/SchemaControl.ts +209 -0
- package/src/security/primitives/$issuer.ts +6 -3
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +75 -0
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +306 -0
- package/src/server/core/errors/ValidationError.ts +13 -1
- package/src/server/core/primitives/$action.ts +16 -5
- package/src/server/core/providers/ServerRouterProvider.ts +26 -4
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -7
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +10 -4
- package/src/websocket/services/WebSocketClient.ts +11 -5
- package/src/mcp/transports/SseMcpTransport.ts +0 -182
package/dist/react/ui/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as _$alepha from "alepha";
|
|
|
2
2
|
import { Static } from "alepha";
|
|
3
3
|
import * as _$alepha_react_head0 from "alepha/react/head";
|
|
4
4
|
import * as _$alepha_server_cookies0 from "alepha/server/cookies";
|
|
5
|
+
import { FormModel } from "alepha/react/form";
|
|
5
6
|
import * as _$typebox from "typebox";
|
|
6
7
|
|
|
7
8
|
//#region ../../src/react/ui/atoms/uiAtom.d.ts
|
|
@@ -20,6 +21,33 @@ declare const uiAtom: _$alepha.Atom<_$alepha.TObject<{
|
|
|
20
21
|
}>, "alepha.react.ui">;
|
|
21
22
|
type UiState = Static<typeof uiAtom.schema>;
|
|
22
23
|
//#endregion
|
|
24
|
+
//#region ../../src/react/ui/atoms/uiThemeListAtom.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* Available themes the user can pick from. Apps populate this atom on boot
|
|
27
|
+
* (e.g. `alepha.store.set(uiThemeListAtom, MY_THEMES)`); UI consumers like
|
|
28
|
+
* `<ButtonTheme/>` read it to render a picker. The selected theme id is
|
|
29
|
+
* persisted separately in `uiAtom.theme`.
|
|
30
|
+
*
|
|
31
|
+
* Defaults to a single `"default"` entry so the registry stays usable when
|
|
32
|
+
* an app doesn't declare its own list.
|
|
33
|
+
*/
|
|
34
|
+
declare const uiThemeListAtom: _$alepha.Atom<_$alepha.TArray<_$alepha.TObject<{
|
|
35
|
+
/** Stable id stored in `uiAtom.theme`. Mapped to a CSS class on `<html>`. */id: _$alepha.TString; /** Human-readable label shown in the picker. */
|
|
36
|
+
label: _$alepha.TString;
|
|
37
|
+
/**
|
|
38
|
+
* Optional 4-color preview swatch in 2×2 order (TL, TR, BL, BR). Any
|
|
39
|
+
* CSS-valid color string.
|
|
40
|
+
*/
|
|
41
|
+
swatch: _$alepha.TOptional<_$alepha.TArray<_$alepha.TString>>;
|
|
42
|
+
/**
|
|
43
|
+
* Optional stylesheet URL (typically Google Fonts) loaded lazily when
|
|
44
|
+
* the theme is selected.
|
|
45
|
+
*/
|
|
46
|
+
fontHref: _$alepha.TOptional<_$alepha.TString>;
|
|
47
|
+
}>>, "alepha.react.ui.themes">;
|
|
48
|
+
type UiThemeList = Static<typeof uiThemeListAtom.schema>;
|
|
49
|
+
type UiTheme = UiThemeList[number];
|
|
50
|
+
//#endregion
|
|
23
51
|
//#region ../../src/react/ui/components/ColorScheme.d.ts
|
|
24
52
|
/**
|
|
25
53
|
* Applies `class="dark"` and an optional theme palette class
|
|
@@ -80,6 +108,171 @@ declare const useTheme: () => {
|
|
|
80
108
|
setTheme: (next: string) => void;
|
|
81
109
|
};
|
|
82
110
|
//#endregion
|
|
111
|
+
//#region ../../src/react/ui/services/SchemaControl.d.ts
|
|
112
|
+
/**
|
|
113
|
+
* Schema-bound metadata read by `<Control>` (in `@alepha/ui-registry`) to
|
|
114
|
+
* configure how a field renders. Place under `$control` on any TypeBox
|
|
115
|
+
* schema option.
|
|
116
|
+
*
|
|
117
|
+
* Two forms:
|
|
118
|
+
*
|
|
119
|
+
* 1. **Object** — static configuration baked into the schema:
|
|
120
|
+
* ```ts
|
|
121
|
+
* t.string({ $control: { password: true, icon: "key" } })
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* 2. **Function** — dynamic, computed from current form state:
|
|
125
|
+
* ```ts
|
|
126
|
+
* t.string({
|
|
127
|
+
* $control: ({ form, value }) => {
|
|
128
|
+
* if (form.currentValues.kind !== "advanced") return false; // hide
|
|
129
|
+
* return { items: () => fetchOptions(form.currentValues.kind) };
|
|
130
|
+
* },
|
|
131
|
+
* })
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* The function may return:
|
|
135
|
+
* - a partial `SchemaControl` to merge with explicit `<Control>` props
|
|
136
|
+
* - `false` to hide the control entirely
|
|
137
|
+
* - `undefined` to leave the field as-is
|
|
138
|
+
*/
|
|
139
|
+
interface SchemaControl {
|
|
140
|
+
text?: boolean;
|
|
141
|
+
area?: boolean;
|
|
142
|
+
password?: boolean;
|
|
143
|
+
switch?: boolean;
|
|
144
|
+
number?: boolean;
|
|
145
|
+
file?: boolean;
|
|
146
|
+
date?: boolean;
|
|
147
|
+
datetime?: boolean;
|
|
148
|
+
time?: boolean;
|
|
149
|
+
select?: boolean;
|
|
150
|
+
combobox?: boolean;
|
|
151
|
+
segmented?: boolean;
|
|
152
|
+
slider?: boolean;
|
|
153
|
+
object?: boolean;
|
|
154
|
+
array?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Icon name. The registry control maps this to its icon set
|
|
157
|
+
* (lucide-react). Pass `null` to suppress the schema-inferred icon.
|
|
158
|
+
*/
|
|
159
|
+
icon?: string | null;
|
|
160
|
+
label?: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
placeholder?: string;
|
|
163
|
+
/**
|
|
164
|
+
* HTML `autocomplete` attribute. Use standard tokens like
|
|
165
|
+
* `"username"`, `"email"`, `"new-password"`, `"current-password"`,
|
|
166
|
+
* `"street-address"`, `"address-line1"`, `"address-level2"` (city),
|
|
167
|
+
* `"postal-code"`, `"country"`, `"cc-number"`, `"cc-exp"`,
|
|
168
|
+
* `"cc-csc"`, `"cc-name"`, `"tel"`, etc.
|
|
169
|
+
*/
|
|
170
|
+
autoComplete?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Static or async option list for select / combobox / multi-select.
|
|
173
|
+
* Each item is either a bare string (used as both value & label) or a
|
|
174
|
+
* `{ value, label, description?, tag? }` object.
|
|
175
|
+
*/
|
|
176
|
+
items?: Array<string | SchemaControlItem> | SchemaControlItemsFn;
|
|
177
|
+
/**
|
|
178
|
+
* Re-fetch `items` (when async) whenever any of these reference values
|
|
179
|
+
* change. Useful for cascading selects.
|
|
180
|
+
*/
|
|
181
|
+
itemsWatch?: unknown[];
|
|
182
|
+
/**
|
|
183
|
+
* Allow the user to create a new option by typing into a select /
|
|
184
|
+
* multi-select. Pass `true` for `{ value: query, label: query }`, or a
|
|
185
|
+
* function returning a custom option built from the query.
|
|
186
|
+
*/
|
|
187
|
+
createNewEntry?: boolean | ((query: string) => {
|
|
188
|
+
value: string;
|
|
189
|
+
label: string;
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* Width slot inside an `<AutoForm>` group. Mapped to a grid column span.
|
|
193
|
+
* - `100` → full row
|
|
194
|
+
* - `75` → 3/4 row
|
|
195
|
+
* - `66` → 2/3 row
|
|
196
|
+
* - `50` → half
|
|
197
|
+
* - `33` → one third (default for plain primitives)
|
|
198
|
+
* - `25` → one quarter
|
|
199
|
+
*/
|
|
200
|
+
width?: 100 | 75 | 66 | 50 | 33 | 25;
|
|
201
|
+
/**
|
|
202
|
+
* Render `null` (hide) when truthy. Equivalent to a function `$control`
|
|
203
|
+
* returning `false`, but available as a static value.
|
|
204
|
+
*/
|
|
205
|
+
hidden?: boolean;
|
|
206
|
+
disabled?: boolean;
|
|
207
|
+
readOnly?: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Render before/after the field. Both receive the resolved input.
|
|
210
|
+
* Typed loosely — UI layer narrows to `ReactNode`.
|
|
211
|
+
*/
|
|
212
|
+
top?: unknown;
|
|
213
|
+
bottom?: unknown;
|
|
214
|
+
/**
|
|
215
|
+
* Render a managed upload control (image preview, multi, drag-drop)
|
|
216
|
+
* that posts to the file API and stores the resulting file ID(s) in
|
|
217
|
+
* the form. Pass `true` for defaults or an options object:
|
|
218
|
+
*
|
|
219
|
+
* ```ts
|
|
220
|
+
* $control: { upload: { multi: true, accept: "image/*", maxSize: 5_000_000 } }
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
upload?: boolean | {
|
|
224
|
+
multi?: boolean;
|
|
225
|
+
accept?: string;
|
|
226
|
+
maxSize?: number;
|
|
227
|
+
bucket?: string;
|
|
228
|
+
};
|
|
229
|
+
arrayProps?: {
|
|
230
|
+
confirmDelete?: boolean | {
|
|
231
|
+
title?: string;
|
|
232
|
+
message?: string;
|
|
233
|
+
}; /** Computed label for each tab when an array uses tabs mode. */
|
|
234
|
+
renderTabName?: (i: number, value: unknown) => string;
|
|
235
|
+
sortable?: boolean;
|
|
236
|
+
collapsible?: boolean; /** Force grouped (CreateForm-style) tabs even for short arrays. */
|
|
237
|
+
forceTabs?: boolean;
|
|
238
|
+
};
|
|
239
|
+
[key: string]: unknown;
|
|
240
|
+
}
|
|
241
|
+
interface SchemaControlItem {
|
|
242
|
+
value: string | number | boolean;
|
|
243
|
+
label: string;
|
|
244
|
+
description?: string;
|
|
245
|
+
tag?: string;
|
|
246
|
+
}
|
|
247
|
+
type SchemaControlItemsFn = (query: string) => Array<string | SchemaControlItem> | Promise<Array<string | SchemaControlItem>>;
|
|
248
|
+
/**
|
|
249
|
+
* Function form of `$control`. Receives the live form model + the current
|
|
250
|
+
* field value, and returns a partial config (merged with explicit props),
|
|
251
|
+
* `false` to hide, or `undefined` to leave as-is.
|
|
252
|
+
*/
|
|
253
|
+
type SchemaControlFn = (context: {
|
|
254
|
+
form: FormModel<any>;
|
|
255
|
+
value: unknown;
|
|
256
|
+
}) => Partial<SchemaControl> | false | undefined;
|
|
257
|
+
type SchemaControlOption = SchemaControl | SchemaControlFn;
|
|
258
|
+
/**
|
|
259
|
+
* Resolve a raw `$control` value (object or function) into a concrete
|
|
260
|
+
* partial config. Returns `null` when the field should be hidden.
|
|
261
|
+
*/
|
|
262
|
+
declare const resolveSchemaControl: (raw: unknown, context: {
|
|
263
|
+
form: FormModel<any>;
|
|
264
|
+
value: unknown;
|
|
265
|
+
}) => Partial<SchemaControl> | null;
|
|
266
|
+
declare module "typebox" {
|
|
267
|
+
interface TSchemaOptions {
|
|
268
|
+
/**
|
|
269
|
+
* UI metadata read by `<Control>` from `@alepha/ui-registry`. See
|
|
270
|
+
* {@link SchemaControl}.
|
|
271
|
+
*/
|
|
272
|
+
$control?: SchemaControlOption;
|
|
273
|
+
}
|
|
274
|
+
} //# sourceMappingURL=SchemaControl.d.ts.map
|
|
275
|
+
//#endregion
|
|
83
276
|
//#region ../../src/react/ui/services/UiPersistence.d.ts
|
|
84
277
|
/**
|
|
85
278
|
* Binds the {@link uiAtom} to an `alepha-ui` cookie + injects an inline
|
|
@@ -108,6 +301,7 @@ declare class UiPersistence {
|
|
|
108
301
|
declare module "alepha" {
|
|
109
302
|
interface State {
|
|
110
303
|
"alepha.react.ui": UiState;
|
|
304
|
+
"alepha.react.ui.themes": UiThemeList;
|
|
111
305
|
}
|
|
112
306
|
}
|
|
113
307
|
/**
|
|
@@ -120,5 +314,5 @@ declare module "alepha" {
|
|
|
120
314
|
*/
|
|
121
315
|
declare const AlephaReactUi: _$alepha.Service<_$alepha.Module>;
|
|
122
316
|
//#endregion
|
|
123
|
-
export { AlephaReactUi, ColorMode, ColorScheme, ResolvedColorMode, UiPersistence, UiState, uiAtom, useColorMode, useSidebarState, useTheme };
|
|
317
|
+
export { AlephaReactUi, ColorMode, ColorScheme, ResolvedColorMode, SchemaControl, SchemaControlFn, SchemaControlItem, SchemaControlItemsFn, SchemaControlOption, UiPersistence, UiState, UiTheme, UiThemeList, resolveSchemaControl, uiAtom, uiThemeListAtom, useColorMode, useSidebarState, useTheme };
|
|
124
318
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/react/ui/atoms/uiAtom.ts","../../../src/react/ui/components/ColorScheme.tsx","../../../src/react/ui/hooks/useColorMode.ts","../../../src/react/ui/hooks/useSidebarState.ts","../../../src/react/ui/hooks/useTheme.ts","../../../src/react/ui/services/UiPersistence.ts","../../../src/react/ui/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/react/ui/atoms/uiAtom.ts","../../../src/react/ui/atoms/uiThemeListAtom.ts","../../../src/react/ui/components/ColorScheme.tsx","../../../src/react/ui/hooks/useColorMode.ts","../../../src/react/ui/hooks/useSidebarState.ts","../../../src/react/ui/hooks/useTheme.ts","../../../src/react/ui/services/SchemaControl.ts","../../../src/react/ui/services/UiPersistence.ts","../../../src/react/ui/index.ts"],"mappings":";;;;;;;;;;;;;;cAQa,MAAA,EAAM,QAAA,CAAA,IAAA,UAAA,OAAA;EAAN,4EAiBX,QAAA,CAAA,OAAA;;;;;;KAEU,OAAA,GAAU,MAAA,QAAc,MAAA,CAAO,MAAA;;;;;;;;;;AAnB3C;;cCGa,eAAA,EAAe,QAAA,CAAA,IAAA,CAAA,QAAA,CAAA,MAAA,UAAA,OAAA;EDc1B,iFCOA,QAAA,CAAA,OAAA;;;;;;;EDxBiB;;;;;;KC0BP,WAAA,GAAc,MAAA,QAAc,eAAA,CAAgB,MAAA;AAAA,KAC5C,OAAA,GAAU,WAAA;;;;;;;;;;;AD3BtB;;iBEMgB,WAAA,CAAA;;;KCVJ,SAAA;AAAA,KACA,iBAAA;;;;;;;AHGZ;;;cGQa,YAAA;;;kBAQO,SAAA;AAAA;;;;;;;;;;;cCbP,eAAA;;;;;;;;;;;;;;;cCAA,QAAA;;;;;;;;;;;;;ALHb;;;;;;;;;;;;;;;;;;;;UMqBiB,aAAA;EAEf,IAAA;EACA,IAAA;EACA,QAAA;EACA,MAAA;EACA,MAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,MAAA;EACA,KAAA;ELbA;;;;EKoBA,IAAA;EACA,KAAA;EACA,WAAA;EACA,WAAA;;;;;;;;EAQA,YAAA;ELpD0B;;;;;EK4D1B,KAAA,GAAQ,KAAA,UAAe,iBAAA,IAAqB,oBAAA;;;;;EAM5C,UAAA;;;;AL3CF;;EKkDE,cAAA,eAEM,KAAA;IAAoB,KAAA;IAAe,KAAA;EAAA;ELpDa;;;AACxD;;;;;;EK+DE,KAAA;;AJpFF;;;EI2FE,MAAA;EACA,QAAA;EACA,QAAA;;;AHvGF;;EG8GE,GAAA;EACA,MAAA;EH/GmB;AACrB;;;;;AAWA;;;EG+GE,MAAA;IAGM,KAAA;IACA,MAAA;IACA,OAAA;IACA,MAAA;EAAA;EAIN,UAAA;IACE,aAAA;MAA4B,KAAA;MAAgB,OAAA;IAAA;IAE5C,aAAA,IAAiB,CAAA,UAAW,KAAA;IAC5B,QAAA;IACA,WAAA;IAEA,SAAA;EAAA;EAAA,CAID,GAAA;AAAA;AAAA,UAGc,iBAAA;EACf,KAAA;EACA,KAAA;EACA,WAAA;EACA,GAAA;AAAA;AAAA,KAGU,oBAAA,IACV,KAAA,aAEE,KAAA,UAAe,iBAAA,IACf,OAAA,CAAQ,KAAA,UAAe,iBAAA;;;;ADvJ3B;;KC8JY,eAAA,IAAmB,OAAA;EAC7B,IAAA,EAAM,SAAA;EACN,KAAA;AAAA,MACI,OAAA,CAAQ,aAAA;AAAA,KAEF,mBAAA,GAAsB,aAAA,GAAgB,eAAA;;;;;cAMrC,oBAAA,GACX,GAAA,WACA,OAAA;EAAW,IAAA,EAAM,SAAA;EAAgB,KAAA;AAAA,MAChC,OAAA,CAAQ,aAAA;AAAA;EAAA,UAkBC,cAAA;IAlIkC;;;;IAuI1C,QAAA,GAAW,mBAAA;EAAA;AAAA;;;;;;;;;;;ANtMf;;;;cOoBa,aAAA;EACX,EAAA,EAAE,wBAAA,CAAA,uBAAA,WAAA,OAAA;UADsB,SAAA,CAAA,OAAA;;;;;;EASxB,IAAA,EARE,oBAAA,CAQE,aAAA;AAAA;;;;YCjBa,KAAA;IACf,iBAAA,EAAmB,OAAA;IACnB,wBAAA,EAA0B,WAAA;EAAA;AAAA;;;;;;;;;cAcjB,aAAA,EAAa,QAAA,CAAA,OAAA,CAIxB,QAAA,CAJwB,MAAA"}
|
package/dist/react/ui/index.js
CHANGED
|
@@ -3,6 +3,43 @@ import { $head } from "alepha/react/head";
|
|
|
3
3
|
import { $cookie } from "alepha/server/cookies";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { useStore } from "alepha/react";
|
|
6
|
+
//#region ../../src/react/ui/atoms/uiThemeListAtom.ts
|
|
7
|
+
/**
|
|
8
|
+
* Available themes the user can pick from. Apps populate this atom on boot
|
|
9
|
+
* (e.g. `alepha.store.set(uiThemeListAtom, MY_THEMES)`); UI consumers like
|
|
10
|
+
* `<ButtonTheme/>` read it to render a picker. The selected theme id is
|
|
11
|
+
* persisted separately in `uiAtom.theme`.
|
|
12
|
+
*
|
|
13
|
+
* Defaults to a single `"default"` entry so the registry stays usable when
|
|
14
|
+
* an app doesn't declare its own list.
|
|
15
|
+
*/
|
|
16
|
+
const uiThemeListAtom = $atom({
|
|
17
|
+
name: "alepha.react.ui.themes",
|
|
18
|
+
schema: t.array(t.object({
|
|
19
|
+
/** Stable id stored in `uiAtom.theme`. Mapped to a CSS class on `<html>`. */
|
|
20
|
+
id: t.string(),
|
|
21
|
+
/** Human-readable label shown in the picker. */
|
|
22
|
+
label: t.string(),
|
|
23
|
+
/**
|
|
24
|
+
* Optional 4-color preview swatch in 2×2 order (TL, TR, BL, BR). Any
|
|
25
|
+
* CSS-valid color string.
|
|
26
|
+
*/
|
|
27
|
+
swatch: t.optional(t.array(t.string(), {
|
|
28
|
+
minItems: 4,
|
|
29
|
+
maxItems: 4
|
|
30
|
+
})),
|
|
31
|
+
/**
|
|
32
|
+
* Optional stylesheet URL (typically Google Fonts) loaded lazily when
|
|
33
|
+
* the theme is selected.
|
|
34
|
+
*/
|
|
35
|
+
fontHref: t.optional(t.string())
|
|
36
|
+
})),
|
|
37
|
+
default: [{
|
|
38
|
+
id: "default",
|
|
39
|
+
label: "Default"
|
|
40
|
+
}]
|
|
41
|
+
});
|
|
42
|
+
//#endregion
|
|
6
43
|
//#region ../../src/react/ui/atoms/uiAtom.ts
|
|
7
44
|
/**
|
|
8
45
|
* Persisted UI state — color mode, theme palette, sidebar collapsed state, etc.
|
|
@@ -190,6 +227,28 @@ const useSidebarState = () => {
|
|
|
190
227
|
};
|
|
191
228
|
};
|
|
192
229
|
//#endregion
|
|
230
|
+
//#region ../../src/react/ui/services/SchemaControl.ts
|
|
231
|
+
/**
|
|
232
|
+
* Resolve a raw `$control` value (object or function) into a concrete
|
|
233
|
+
* partial config. Returns `null` when the field should be hidden.
|
|
234
|
+
*/
|
|
235
|
+
const resolveSchemaControl = (raw, context) => {
|
|
236
|
+
if (raw == null) return {};
|
|
237
|
+
if (typeof raw === "function") {
|
|
238
|
+
const result = raw(context);
|
|
239
|
+
if (result === false) return null;
|
|
240
|
+
if (!result) return {};
|
|
241
|
+
if (result.hidden) return null;
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
if (typeof raw === "object") {
|
|
245
|
+
const obj = raw;
|
|
246
|
+
if (obj.hidden) return null;
|
|
247
|
+
return obj;
|
|
248
|
+
}
|
|
249
|
+
return {};
|
|
250
|
+
};
|
|
251
|
+
//#endregion
|
|
193
252
|
//#region ../../src/react/ui/index.ts
|
|
194
253
|
/**
|
|
195
254
|
* Persisted UI state: color mode, theme palette, sidebar collapsed state.
|
|
@@ -201,9 +260,10 @@ const useSidebarState = () => {
|
|
|
201
260
|
*/
|
|
202
261
|
const AlephaReactUi = $module({
|
|
203
262
|
name: "alepha.react.ui",
|
|
263
|
+
atoms: [uiThemeListAtom],
|
|
204
264
|
services: [UiPersistence]
|
|
205
265
|
});
|
|
206
266
|
//#endregion
|
|
207
|
-
export { AlephaReactUi, ColorScheme, UiPersistence, uiAtom, useColorMode, useSidebarState, useTheme };
|
|
267
|
+
export { AlephaReactUi, ColorScheme, UiPersistence, resolveSchemaControl, uiAtom, uiThemeListAtom, useColorMode, useSidebarState, useTheme };
|
|
208
268
|
|
|
209
269
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/react/ui/atoms/uiAtom.ts","../../../src/react/ui/services/UiPersistence.ts","../../../src/react/ui/hooks/useColorMode.ts","../../../src/react/ui/hooks/useTheme.ts","../../../src/react/ui/components/ColorScheme.tsx","../../../src/react/ui/hooks/useSidebarState.ts","../../../src/react/ui/index.ts"],"sourcesContent":["import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Persisted UI state — color mode, theme palette, sidebar collapsed state, etc.\n *\n * The atom is bound to a single `alepha-ui` cookie via {@link UiPersistence},\n * so values survive page reloads and are available during SSR.\n */\nexport const uiAtom = $atom({\n name: \"alepha.react.ui\",\n schema: t.object({\n /** Color mode preference. `\"system\"` follows the OS-level setting. */\n mode: t.enum([\"light\", \"dark\", \"system\"]),\n /** Theme palette name. UI consumers map this to a CSS class on the root. */\n theme: t.string(),\n /** Sidebar UI state. */\n sidebar: t.object({\n collapsed: t.boolean(),\n }),\n }),\n default: {\n mode: \"system\",\n theme: \"default\",\n sidebar: { collapsed: false },\n },\n});\n\nexport type UiState = Static<typeof uiAtom.schema>;\n","import { $head } from \"alepha/react/head\";\nimport { $cookie } from \"alepha/server/cookies\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Inline `<script>` rendered by SSR into the document `<head>`. Runs\n * synchronously before any CSS or React hydration: reads the `alepha-ui`\n * cookie, resolves `mode === \"system\"` via `prefers-color-scheme`, and\n * applies `class=\"dark\"` (and optional `theme-<name>`) on `<html>`.\n *\n * This is what kills the flash-of-wrong-theme (FOUC) you'd otherwise get\n * with React-effect-based theming. Failures are swallowed silently — at\n * worst the page paints in light mode for one frame.\n */\nconst colorSchemeBoot = `(function(){try{var m=document.cookie.match(/(?:^|;\\\\s*)alepha-ui=([^;]+)/);var s=m?JSON.parse(decodeURIComponent(m[1])):{};var mode=s.mode||\"system\";var dark=mode===\"dark\"||(mode===\"system\"&&window.matchMedia&&window.matchMedia(\"(prefers-color-scheme: dark)\").matches);var r=document.documentElement;if(dark)r.classList.add(\"dark\");if(s.theme&&s.theme!==\"default\")r.classList.add(\"theme-\"+s.theme);}catch(e){}})();`;\n\n/**\n * Binds the {@link uiAtom} to an `alepha-ui` cookie + injects an inline\n * boot script into the SSR head to prevent FOUC on first paint.\n *\n * Reading flow: on app boot the cookie is parsed and pushed into the atom\n * (via the `key` option on `$cookie`). Writing flow: every time the atom\n * mutates, the cookie is rewritten — a single `useStore(uiAtom)` call is\n * enough to persist UI preferences across reloads.\n *\n * Persists for 365 days; SameSite=lax so it travels on top-level navigation\n * but not on cross-origin requests.\n */\nexport class UiPersistence {\n ui = $cookie({\n name: \"alepha-ui\",\n key: uiAtom.key,\n schema: uiAtom.schema,\n ttl: [365, \"days\"],\n sameSite: \"lax\",\n });\n\n head = $head({\n script: [{ content: colorSchemeBoot }],\n });\n}\n","import { useStore } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\nexport type ColorMode = \"light\" | \"dark\" | \"system\";\nexport type ResolvedColorMode = \"light\" | \"dark\";\n\n/**\n * Read and update the user's color-mode preference. `\"system\"` resolves to\n * the OS preference and updates live as the OS toggles between light/dark.\n *\n * @example\n * const { mode, setMode, resolved } = useColorMode();\n * setMode(\"dark\");\n * document.documentElement.classList.toggle(\"dark\", resolved === \"dark\");\n */\nexport const useColorMode = () => {\n const [state, set] = useStore(uiAtom);\n const mode = (state?.mode ?? \"system\") as ColorMode;\n const resolved = useResolvedColorMode(mode);\n\n return {\n mode,\n resolved,\n setMode: (next: ColorMode) => {\n set({ ...(state ?? uiAtom.options.default!), mode: next });\n },\n };\n};\n\nconst useResolvedColorMode = (mode: ColorMode): ResolvedColorMode => {\n const [systemDark, setSystemDark] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches ?? false;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia?.(\"(prefers-color-scheme: dark)\");\n if (!mq) return;\n const onChange = (ev: MediaQueryListEvent) => setSystemDark(ev.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n\n if (mode === \"dark\") return \"dark\";\n if (mode === \"light\") return \"light\";\n return systemDark ? \"dark\" : \"light\";\n};\n","import { useStore } from \"alepha/react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Read and update the active theme palette name. UI consumers typically map\n * the value to a class on the document root (e.g. `theme-claude`).\n *\n * @example\n * const { theme, setTheme } = useTheme();\n * setTheme(\"claude\");\n */\nexport const useTheme = () => {\n const [state, set] = useStore(uiAtom);\n const theme = state?.theme ?? \"default\";\n\n return {\n theme,\n setTheme: (next: string) => {\n set({ ...(state ?? uiAtom.options.default!), theme: next });\n },\n };\n};\n","import { useEffect } from \"react\";\nimport { useColorMode } from \"../hooks/useColorMode.ts\";\nimport { useTheme } from \"../hooks/useTheme.ts\";\n\n/**\n * Applies `class=\"dark\"` and an optional theme palette class\n * (`theme-<name>`) to the document root, syncing whenever the underlying\n * atom mutates.\n *\n * Mount once near the root of your tree (typically inside the layout).\n *\n * @example\n * <ColorScheme />\n */\nexport function ColorScheme() {\n const { resolved } = useColorMode();\n const { theme } = useTheme();\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n document.documentElement.classList.toggle(\"dark\", resolved === \"dark\");\n }, [resolved]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n const previous: string[] = [];\n root.classList.forEach((cls) => {\n if (cls.startsWith(\"theme-\")) previous.push(cls);\n });\n for (const cls of previous) root.classList.remove(cls);\n if (theme && theme !== \"default\") root.classList.add(`theme-${theme}`);\n }, [theme]);\n\n return null;\n}\n","import { useStore } from \"alepha/react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Read and update the sidebar collapsed state. The value is persisted via the\n * `alepha-ui` cookie so it survives reloads and is available during SSR — no\n * flash of expanded-then-collapsed when the user prefers a collapsed shell.\n *\n * @example\n * const { collapsed, setCollapsed, toggle } = useSidebarState();\n */\nexport const useSidebarState = () => {\n const [state, set] = useStore(uiAtom);\n const collapsed = state?.sidebar.collapsed ?? false;\n\n const setCollapsed = (next: boolean) => {\n const base = state ?? uiAtom.options.default!;\n set({ ...base, sidebar: { ...base.sidebar, collapsed: next } });\n };\n\n return {\n collapsed,\n setCollapsed,\n toggle: () => setCollapsed(!collapsed),\n };\n};\n","import { $module } from \"alepha\";\nimport type { UiState } from \"./atoms/uiAtom.ts\";\nimport { UiPersistence } from \"./services/UiPersistence.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./atoms/uiAtom.ts\";\nexport * from \"./components/ColorScheme.tsx\";\nexport * from \"./hooks/useColorMode.ts\";\nexport * from \"./hooks/useSidebarState.ts\";\nexport * from \"./hooks/useTheme.ts\";\nexport * from \"./services/UiPersistence.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n export interface State {\n \"alepha.react.ui\": UiState;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Persisted UI state: color mode, theme palette, sidebar collapsed state.\n *\n * Backed by an `alepha-ui` cookie so preferences survive reloads and are\n * available during SSR (no flash of wrong theme).\n *\n * @module alepha.react.ui\n */\nexport const AlephaReactUi = $module({\n name: \"alepha.react.ui\",\n services: [UiPersistence],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/react/ui/atoms/uiThemeListAtom.ts","../../../src/react/ui/atoms/uiAtom.ts","../../../src/react/ui/services/UiPersistence.ts","../../../src/react/ui/hooks/useColorMode.ts","../../../src/react/ui/hooks/useTheme.ts","../../../src/react/ui/components/ColorScheme.tsx","../../../src/react/ui/hooks/useSidebarState.ts","../../../src/react/ui/services/SchemaControl.ts","../../../src/react/ui/index.ts"],"sourcesContent":["import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Available themes the user can pick from. Apps populate this atom on boot\n * (e.g. `alepha.store.set(uiThemeListAtom, MY_THEMES)`); UI consumers like\n * `<ButtonTheme/>` read it to render a picker. The selected theme id is\n * persisted separately in `uiAtom.theme`.\n *\n * Defaults to a single `\"default\"` entry so the registry stays usable when\n * an app doesn't declare its own list.\n */\nexport const uiThemeListAtom = $atom({\n name: \"alepha.react.ui.themes\",\n schema: t.array(\n t.object({\n /** Stable id stored in `uiAtom.theme`. Mapped to a CSS class on `<html>`. */\n id: t.string(),\n /** Human-readable label shown in the picker. */\n label: t.string(),\n /**\n * Optional 4-color preview swatch in 2×2 order (TL, TR, BL, BR). Any\n * CSS-valid color string.\n */\n swatch: t.optional(t.array(t.string(), { minItems: 4, maxItems: 4 })),\n /**\n * Optional stylesheet URL (typically Google Fonts) loaded lazily when\n * the theme is selected.\n */\n fontHref: t.optional(t.string()),\n }),\n ),\n default: [{ id: \"default\", label: \"Default\" }],\n});\n\nexport type UiThemeList = Static<typeof uiThemeListAtom.schema>;\nexport type UiTheme = UiThemeList[number];\n","import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Persisted UI state — color mode, theme palette, sidebar collapsed state, etc.\n *\n * The atom is bound to a single `alepha-ui` cookie via {@link UiPersistence},\n * so values survive page reloads and are available during SSR.\n */\nexport const uiAtom = $atom({\n name: \"alepha.react.ui\",\n schema: t.object({\n /** Color mode preference. `\"system\"` follows the OS-level setting. */\n mode: t.enum([\"light\", \"dark\", \"system\"]),\n /** Theme palette name. UI consumers map this to a CSS class on the root. */\n theme: t.string(),\n /** Sidebar UI state. */\n sidebar: t.object({\n collapsed: t.boolean(),\n }),\n }),\n default: {\n mode: \"system\",\n theme: \"default\",\n sidebar: { collapsed: false },\n },\n});\n\nexport type UiState = Static<typeof uiAtom.schema>;\n","import { $head } from \"alepha/react/head\";\nimport { $cookie } from \"alepha/server/cookies\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Inline `<script>` rendered by SSR into the document `<head>`. Runs\n * synchronously before any CSS or React hydration: reads the `alepha-ui`\n * cookie, resolves `mode === \"system\"` via `prefers-color-scheme`, and\n * applies `class=\"dark\"` (and optional `theme-<name>`) on `<html>`.\n *\n * This is what kills the flash-of-wrong-theme (FOUC) you'd otherwise get\n * with React-effect-based theming. Failures are swallowed silently — at\n * worst the page paints in light mode for one frame.\n */\nconst colorSchemeBoot = `(function(){try{var m=document.cookie.match(/(?:^|;\\\\s*)alepha-ui=([^;]+)/);var s=m?JSON.parse(decodeURIComponent(m[1])):{};var mode=s.mode||\"system\";var dark=mode===\"dark\"||(mode===\"system\"&&window.matchMedia&&window.matchMedia(\"(prefers-color-scheme: dark)\").matches);var r=document.documentElement;if(dark)r.classList.add(\"dark\");if(s.theme&&s.theme!==\"default\")r.classList.add(\"theme-\"+s.theme);}catch(e){}})();`;\n\n/**\n * Binds the {@link uiAtom} to an `alepha-ui` cookie + injects an inline\n * boot script into the SSR head to prevent FOUC on first paint.\n *\n * Reading flow: on app boot the cookie is parsed and pushed into the atom\n * (via the `key` option on `$cookie`). Writing flow: every time the atom\n * mutates, the cookie is rewritten — a single `useStore(uiAtom)` call is\n * enough to persist UI preferences across reloads.\n *\n * Persists for 365 days; SameSite=lax so it travels on top-level navigation\n * but not on cross-origin requests.\n */\nexport class UiPersistence {\n ui = $cookie({\n name: \"alepha-ui\",\n key: uiAtom.key,\n schema: uiAtom.schema,\n ttl: [365, \"days\"],\n sameSite: \"lax\",\n });\n\n head = $head({\n script: [{ content: colorSchemeBoot }],\n });\n}\n","import { useStore } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\nexport type ColorMode = \"light\" | \"dark\" | \"system\";\nexport type ResolvedColorMode = \"light\" | \"dark\";\n\n/**\n * Read and update the user's color-mode preference. `\"system\"` resolves to\n * the OS preference and updates live as the OS toggles between light/dark.\n *\n * @example\n * const { mode, setMode, resolved } = useColorMode();\n * setMode(\"dark\");\n * document.documentElement.classList.toggle(\"dark\", resolved === \"dark\");\n */\nexport const useColorMode = () => {\n const [state, set] = useStore(uiAtom);\n const mode = (state?.mode ?? \"system\") as ColorMode;\n const resolved = useResolvedColorMode(mode);\n\n return {\n mode,\n resolved,\n setMode: (next: ColorMode) => {\n set({ ...(state ?? uiAtom.options.default!), mode: next });\n },\n };\n};\n\nconst useResolvedColorMode = (mode: ColorMode): ResolvedColorMode => {\n const [systemDark, setSystemDark] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches ?? false;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia?.(\"(prefers-color-scheme: dark)\");\n if (!mq) return;\n const onChange = (ev: MediaQueryListEvent) => setSystemDark(ev.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n\n if (mode === \"dark\") return \"dark\";\n if (mode === \"light\") return \"light\";\n return systemDark ? \"dark\" : \"light\";\n};\n","import { useStore } from \"alepha/react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Read and update the active theme palette name. UI consumers typically map\n * the value to a class on the document root (e.g. `theme-claude`).\n *\n * @example\n * const { theme, setTheme } = useTheme();\n * setTheme(\"claude\");\n */\nexport const useTheme = () => {\n const [state, set] = useStore(uiAtom);\n const theme = state?.theme ?? \"default\";\n\n return {\n theme,\n setTheme: (next: string) => {\n set({ ...(state ?? uiAtom.options.default!), theme: next });\n },\n };\n};\n","import { useEffect } from \"react\";\nimport { useColorMode } from \"../hooks/useColorMode.ts\";\nimport { useTheme } from \"../hooks/useTheme.ts\";\n\n/**\n * Applies `class=\"dark\"` and an optional theme palette class\n * (`theme-<name>`) to the document root, syncing whenever the underlying\n * atom mutates.\n *\n * Mount once near the root of your tree (typically inside the layout).\n *\n * @example\n * <ColorScheme />\n */\nexport function ColorScheme() {\n const { resolved } = useColorMode();\n const { theme } = useTheme();\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n document.documentElement.classList.toggle(\"dark\", resolved === \"dark\");\n }, [resolved]);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n const previous: string[] = [];\n root.classList.forEach((cls) => {\n if (cls.startsWith(\"theme-\")) previous.push(cls);\n });\n for (const cls of previous) root.classList.remove(cls);\n if (theme && theme !== \"default\") root.classList.add(`theme-${theme}`);\n }, [theme]);\n\n return null;\n}\n","import { useStore } from \"alepha/react\";\nimport { uiAtom } from \"../atoms/uiAtom.ts\";\n\n/**\n * Read and update the sidebar collapsed state. The value is persisted via the\n * `alepha-ui` cookie so it survives reloads and is available during SSR — no\n * flash of expanded-then-collapsed when the user prefers a collapsed shell.\n *\n * @example\n * const { collapsed, setCollapsed, toggle } = useSidebarState();\n */\nexport const useSidebarState = () => {\n const [state, set] = useStore(uiAtom);\n const collapsed = state?.sidebar.collapsed ?? false;\n\n const setCollapsed = (next: boolean) => {\n const base = state ?? uiAtom.options.default!;\n set({ ...base, sidebar: { ...base.sidebar, collapsed: next } });\n };\n\n return {\n collapsed,\n setCollapsed,\n toggle: () => setCollapsed(!collapsed),\n };\n};\n","import type { FormModel } from \"alepha/react/form\";\n\n/**\n * Schema-bound metadata read by `<Control>` (in `@alepha/ui-registry`) to\n * configure how a field renders. Place under `$control` on any TypeBox\n * schema option.\n *\n * Two forms:\n *\n * 1. **Object** — static configuration baked into the schema:\n * ```ts\n * t.string({ $control: { password: true, icon: \"key\" } })\n * ```\n *\n * 2. **Function** — dynamic, computed from current form state:\n * ```ts\n * t.string({\n * $control: ({ form, value }) => {\n * if (form.currentValues.kind !== \"advanced\") return false; // hide\n * return { items: () => fetchOptions(form.currentValues.kind) };\n * },\n * })\n * ```\n *\n * The function may return:\n * - a partial `SchemaControl` to merge with explicit `<Control>` props\n * - `false` to hide the control entirely\n * - `undefined` to leave the field as-is\n */\nexport interface SchemaControl {\n // ── Variant forcing ────────────────────────────────────────────────\n text?: boolean;\n area?: boolean;\n password?: boolean;\n switch?: boolean;\n number?: boolean;\n file?: boolean;\n date?: boolean;\n datetime?: boolean;\n time?: boolean;\n select?: boolean;\n combobox?: boolean;\n segmented?: boolean;\n slider?: boolean;\n object?: boolean;\n array?: boolean;\n\n // ── Labels / hints ────────────────────────────────────────────────\n /**\n * Icon name. The registry control maps this to its icon set\n * (lucide-react). Pass `null` to suppress the schema-inferred icon.\n */\n icon?: string | null;\n label?: string;\n description?: string;\n placeholder?: string;\n /**\n * HTML `autocomplete` attribute. Use standard tokens like\n * `\"username\"`, `\"email\"`, `\"new-password\"`, `\"current-password\"`,\n * `\"street-address\"`, `\"address-line1\"`, `\"address-level2\"` (city),\n * `\"postal-code\"`, `\"country\"`, `\"cc-number\"`, `\"cc-exp\"`,\n * `\"cc-csc\"`, `\"cc-name\"`, `\"tel\"`, etc.\n */\n autoComplete?: string;\n\n // ── Data ──────────────────────────────────────────────────────────\n /**\n * Static or async option list for select / combobox / multi-select.\n * Each item is either a bare string (used as both value & label) or a\n * `{ value, label, description?, tag? }` object.\n */\n items?: Array<string | SchemaControlItem> | SchemaControlItemsFn;\n\n /**\n * Re-fetch `items` (when async) whenever any of these reference values\n * change. Useful for cascading selects.\n */\n itemsWatch?: unknown[];\n\n /**\n * Allow the user to create a new option by typing into a select /\n * multi-select. Pass `true` for `{ value: query, label: query }`, or a\n * function returning a custom option built from the query.\n */\n createNewEntry?:\n | boolean\n | ((query: string) => { value: string; label: string });\n\n // ── Layout ────────────────────────────────────────────────────────\n /**\n * Width slot inside an `<AutoForm>` group. Mapped to a grid column span.\n * - `100` → full row\n * - `75` → 3/4 row\n * - `66` → 2/3 row\n * - `50` → half\n * - `33` → one third (default for plain primitives)\n * - `25` → one quarter\n */\n width?: 100 | 75 | 66 | 50 | 33 | 25;\n\n // ── Behavior ─────────────────────────────────────────────────────\n /**\n * Render `null` (hide) when truthy. Equivalent to a function `$control`\n * returning `false`, but available as a static value.\n */\n hidden?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n\n // ── Slots ─────────────────────────────────────────────────────────\n /**\n * Render before/after the field. Both receive the resolved input.\n * Typed loosely — UI layer narrows to `ReactNode`.\n */\n top?: unknown;\n bottom?: unknown;\n\n // ── File upload ───────────────────────────────────────────────────\n /**\n * Render a managed upload control (image preview, multi, drag-drop)\n * that posts to the file API and stores the resulting file ID(s) in\n * the form. Pass `true` for defaults or an options object:\n *\n * ```ts\n * $control: { upload: { multi: true, accept: \"image/*\", maxSize: 5_000_000 } }\n * ```\n */\n upload?:\n | boolean\n | {\n multi?: boolean;\n accept?: string;\n maxSize?: number;\n bucket?: string;\n };\n\n // ── Array specifics ───────────────────────────────────────────────\n arrayProps?: {\n confirmDelete?: boolean | { title?: string; message?: string };\n /** Computed label for each tab when an array uses tabs mode. */\n renderTabName?: (i: number, value: unknown) => string;\n sortable?: boolean;\n collapsible?: boolean;\n /** Force grouped (CreateForm-style) tabs even for short arrays. */\n forceTabs?: boolean;\n };\n\n // ── Open extension ────────────────────────────────────────────────\n [key: string]: unknown;\n}\n\nexport interface SchemaControlItem {\n value: string | number | boolean;\n label: string;\n description?: string;\n tag?: string;\n}\n\nexport type SchemaControlItemsFn = (\n query: string,\n) =>\n | Array<string | SchemaControlItem>\n | Promise<Array<string | SchemaControlItem>>;\n\n/**\n * Function form of `$control`. Receives the live form model + the current\n * field value, and returns a partial config (merged with explicit props),\n * `false` to hide, or `undefined` to leave as-is.\n */\nexport type SchemaControlFn = (context: {\n form: FormModel<any>;\n value: unknown;\n}) => Partial<SchemaControl> | false | undefined;\n\nexport type SchemaControlOption = SchemaControl | SchemaControlFn;\n\n/**\n * Resolve a raw `$control` value (object or function) into a concrete\n * partial config. Returns `null` when the field should be hidden.\n */\nexport const resolveSchemaControl = (\n raw: unknown,\n context: { form: FormModel<any>; value: unknown },\n): Partial<SchemaControl> | null => {\n if (raw == null) return {};\n if (typeof raw === \"function\") {\n const result = (raw as SchemaControlFn)(context);\n if (result === false) return null;\n if (!result) return {};\n if (result.hidden) return null;\n return result;\n }\n if (typeof raw === \"object\") {\n const obj = raw as SchemaControl;\n if (obj.hidden) return null;\n return obj;\n }\n return {};\n};\n\ndeclare module \"typebox\" {\n interface TSchemaOptions {\n /**\n * UI metadata read by `<Control>` from `@alepha/ui-registry`. See\n * {@link SchemaControl}.\n */\n $control?: SchemaControlOption;\n }\n}\n","import { $module } from \"alepha\";\nimport type { UiState } from \"./atoms/uiAtom.ts\";\nimport type { UiThemeList } from \"./atoms/uiThemeListAtom.ts\";\nimport { uiThemeListAtom } from \"./atoms/uiThemeListAtom.ts\";\nimport { UiPersistence } from \"./services/UiPersistence.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./atoms/uiAtom.ts\";\nexport * from \"./atoms/uiThemeListAtom.ts\";\nexport * from \"./components/ColorScheme.tsx\";\nexport * from \"./hooks/useColorMode.ts\";\nexport * from \"./hooks/useSidebarState.ts\";\nexport * from \"./hooks/useTheme.ts\";\nexport * from \"./services/SchemaControl.ts\";\nexport * from \"./services/UiPersistence.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n export interface State {\n \"alepha.react.ui\": UiState;\n \"alepha.react.ui.themes\": UiThemeList;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Persisted UI state: color mode, theme palette, sidebar collapsed state.\n *\n * Backed by an `alepha-ui` cookie so preferences survive reloads and are\n * available during SSR (no flash of wrong theme).\n *\n * @module alepha.react.ui\n */\nexport const AlephaReactUi = $module({\n name: \"alepha.react.ui\",\n atoms: [uiThemeListAtom],\n services: [UiPersistence],\n});\n"],"mappings":"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"}
|
|
@@ -2,8 +2,6 @@ import * as _$alepha from "alepha";
|
|
|
2
2
|
import { Alepha, Async, KIND, Primitive, Static } from "alepha";
|
|
3
3
|
import { DateTime, DateTimeProvider, DurationLike } from "alepha/datetime";
|
|
4
4
|
import * as _$alepha_logger0 from "alepha/logger";
|
|
5
|
-
import { Cron } from "cron-schedule";
|
|
6
|
-
import * as _$dayjs from "dayjs";
|
|
7
5
|
|
|
8
6
|
//#region ../../src/scheduler/constants/CRON.d.ts
|
|
9
7
|
declare const CRON: {
|
|
@@ -15,6 +13,89 @@ declare const CRON: {
|
|
|
15
13
|
EVERY_DAY_AT_MIDNIGHT: string;
|
|
16
14
|
};
|
|
17
15
|
//#endregion
|
|
16
|
+
//#region ../../../../node_modules/cron-schedule/dist/cron.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* An object with contains for each element of a date, which values are allowed.
|
|
19
|
+
* Everything starting at 0, except for days.
|
|
20
|
+
*/
|
|
21
|
+
interface ICronDefinition {
|
|
22
|
+
readonly seconds: Set<number>;
|
|
23
|
+
readonly minutes: Set<number>;
|
|
24
|
+
readonly hours: Set<number>;
|
|
25
|
+
readonly days: Set<number>;
|
|
26
|
+
readonly months: Set<number>;
|
|
27
|
+
readonly weekdays: Set<number>;
|
|
28
|
+
}
|
|
29
|
+
declare class Cron {
|
|
30
|
+
readonly seconds: ReadonlyArray<number>;
|
|
31
|
+
readonly minutes: ReadonlyArray<number>;
|
|
32
|
+
readonly hours: ReadonlyArray<number>;
|
|
33
|
+
readonly days: ReadonlyArray<number>;
|
|
34
|
+
readonly months: ReadonlyArray<number>;
|
|
35
|
+
readonly weekdays: ReadonlyArray<number>;
|
|
36
|
+
readonly reversed: {
|
|
37
|
+
seconds: ReadonlyArray<number>;
|
|
38
|
+
minutes: ReadonlyArray<number>;
|
|
39
|
+
hours: ReadonlyArray<number>;
|
|
40
|
+
days: ReadonlyArray<number>;
|
|
41
|
+
months: ReadonlyArray<number>;
|
|
42
|
+
weekdays: ReadonlyArray<number>;
|
|
43
|
+
};
|
|
44
|
+
constructor({
|
|
45
|
+
seconds,
|
|
46
|
+
minutes,
|
|
47
|
+
hours,
|
|
48
|
+
days,
|
|
49
|
+
months,
|
|
50
|
+
weekdays
|
|
51
|
+
}: ICronDefinition);
|
|
52
|
+
/**
|
|
53
|
+
* Find the next or previous hour, starting from the given start hour that matches the hour constraint.
|
|
54
|
+
* startHour itself might also be allowed.
|
|
55
|
+
*/
|
|
56
|
+
private findAllowedHour;
|
|
57
|
+
/**
|
|
58
|
+
* Find the next or previous minute, starting from the given start minute that matches the minute constraint.
|
|
59
|
+
* startMinute itself might also be allowed.
|
|
60
|
+
*/
|
|
61
|
+
private findAllowedMinute;
|
|
62
|
+
/**
|
|
63
|
+
* Find the next or previous second, starting from the given start second that matches the second constraint.
|
|
64
|
+
* startSecond itself IS NOT allowed.
|
|
65
|
+
*/
|
|
66
|
+
private findAllowedSecond;
|
|
67
|
+
/**
|
|
68
|
+
* Find the next or previous time, starting from the given start time that matches the hour, minute
|
|
69
|
+
* and second constraints. startTime itself might also be allowed.
|
|
70
|
+
*/
|
|
71
|
+
private findAllowedTime;
|
|
72
|
+
/**
|
|
73
|
+
* Find the next or previous day in the given month, starting from the given startDay
|
|
74
|
+
* that matches either the day or the weekday constraint. startDay itself might also be allowed.
|
|
75
|
+
*/
|
|
76
|
+
private findAllowedDayInMonth;
|
|
77
|
+
/** Gets the next date starting from the given start date or now. */
|
|
78
|
+
getNextDate(startDate?: Date): Date;
|
|
79
|
+
/** Gets the specified amount of future dates starting from the given start date or now. */
|
|
80
|
+
getNextDates(amount: number, startDate?: Date): Date[];
|
|
81
|
+
/**
|
|
82
|
+
* Get an ES6 compatible iterator which iterates over the next dates starting from startDate or now.
|
|
83
|
+
* The iterator runs until the optional endDate is reached or forever.
|
|
84
|
+
*/
|
|
85
|
+
getNextDatesIterator(startDate?: Date, endDate?: Date): Generator<Date, undefined, undefined>;
|
|
86
|
+
/** Gets the previous date starting from the given start date or now. */
|
|
87
|
+
getPrevDate(startDate?: Date): Date;
|
|
88
|
+
/** Gets the specified amount of previous dates starting from the given start date or now. */
|
|
89
|
+
getPrevDates(amount: number, startDate?: Date): Date[];
|
|
90
|
+
/**
|
|
91
|
+
* Get an ES6 compatible iterator which iterates over the previous dates starting from startDate or now.
|
|
92
|
+
* The iterator runs until the optional endDate is reached or forever.
|
|
93
|
+
*/
|
|
94
|
+
getPrevDatesIterator(startDate?: Date, endDate?: Date): Generator<Date, undefined, undefined>;
|
|
95
|
+
/** Returns true when there is a cron date at the given date. */
|
|
96
|
+
matchDate(date: Date): boolean;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
18
99
|
//#region ../../src/scheduler/providers/CronProvider.d.ts
|
|
19
100
|
declare class CronProvider {
|
|
20
101
|
protected readonly dt: DateTimeProvider;
|
|
@@ -34,7 +115,7 @@ declare class CronProvider {
|
|
|
34
115
|
createCronJob(name: string, expression: string, handler: (context: {
|
|
35
116
|
now: DateTime;
|
|
36
117
|
}) => Promise<void>, start?: boolean): void;
|
|
37
|
-
protected run(task: CronJob, now?:
|
|
118
|
+
protected run(task: CronJob, now?: DateTime): void;
|
|
38
119
|
/**
|
|
39
120
|
* Trigger a specific cron job by name.
|
|
40
121
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/scheduler/constants/CRON.ts","../../src/scheduler/providers/CronProvider.ts","../../src/scheduler/primitives/$scheduler.ts","../../src/scheduler/providers/WorkerdCronProvider.ts","../../src/scheduler/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["ICronDefinition","Set","seconds","minutes","hours","days","months","weekdays","Cron","ReadonlyArray","Date","Generator","reversed","constructor","findAllowedHour","findAllowedMinute","findAllowedSecond","findAllowedTime","findAllowedDayInMonth","getNextDate","startDate","getNextDates","amount","getNextDatesIterator","endDate","getPrevDate","getPrevDates","getPrevDatesIterator","matchDate","date"],"sources":["../../src/scheduler/constants/CRON.ts","../../../../node_modules/cron-schedule/dist/cron.d.ts","../../src/scheduler/providers/CronProvider.ts","../../src/scheduler/primitives/$scheduler.ts","../../src/scheduler/providers/WorkerdCronProvider.ts","../../src/scheduler/index.ts"],"x_google_ignoreList":[1],"mappings":"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"}
|