foldkit 0.81.1 → 0.82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/calendar/calendarDate.d.ts +11 -11
- package/dist/calendar/calendarDate.d.ts.map +1 -1
- package/dist/calendar/calendarDate.js +14 -13
- package/dist/calendar/comparison.d.ts +3 -3
- package/dist/calendar/comparison.d.ts.map +1 -1
- package/dist/calendar/comparison.js +5 -5
- package/dist/calendar/info.d.ts +1 -1
- package/dist/calendar/info.d.ts.map +1 -1
- package/dist/calendar/info.js +9 -1
- package/dist/calendar/locale.d.ts +5 -5
- package/dist/calendar/locale.js +23 -2
- package/dist/command/index.d.ts +2 -2
- package/dist/command/index.d.ts.map +1 -1
- package/dist/devTools/overlay.d.ts.map +1 -1
- package/dist/devTools/overlay.js +49 -27
- package/dist/devTools/protocol.d.ts +192 -192
- package/dist/devTools/protocol.d.ts.map +1 -1
- package/dist/devTools/protocol.js +36 -12
- package/dist/devTools/serialize.d.ts.map +1 -1
- package/dist/devTools/serialize.js +4 -4
- package/dist/devTools/store.d.ts.map +1 -1
- package/dist/devTools/store.js +1 -2
- package/dist/devTools/submodelPath.d.ts +1 -1
- package/dist/devTools/summarize.d.ts +6 -6
- package/dist/devTools/summarize.d.ts.map +1 -1
- package/dist/devTools/summarize.js +6 -6
- package/dist/devTools/webSocketBridge.d.ts +1 -1
- package/dist/devTools/webSocketBridge.d.ts.map +1 -1
- package/dist/devTools/webSocketBridge.js +19 -18
- package/dist/fieldValidation/index.d.ts +11 -11
- package/dist/fieldValidation/index.d.ts.map +1 -1
- package/dist/fieldValidation/index.js +8 -7
- package/dist/file/error.d.ts +1 -1
- package/dist/file/file.d.ts +1 -1
- package/dist/file/file.js +1 -1
- package/dist/file/reader.d.ts +4 -4
- package/dist/file/reader.js +5 -5
- package/dist/file/select.js +1 -1
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +4 -3
- package/dist/html/lazy.d.ts.map +1 -1
- package/dist/html/lazy.js +6 -7
- package/dist/managedResource/index.d.ts +2 -2
- package/dist/managedResource/index.d.ts.map +1 -1
- package/dist/managedResource/index.js +2 -2
- package/dist/mount/index.d.ts +1 -1
- package/dist/mount/index.d.ts.map +1 -1
- package/dist/route/parser.d.ts +2 -2
- package/dist/route/parser.d.ts.map +1 -1
- package/dist/route/parser.js +5 -5
- package/dist/runtime/browserListeners.d.ts.map +1 -1
- package/dist/runtime/browserListeners.js +6 -7
- package/dist/runtime/deepFreeze.d.ts +1 -1
- package/dist/runtime/deepFreeze.js +2 -2
- package/dist/runtime/hmrProtocol.d.ts +22 -0
- package/dist/runtime/hmrProtocol.d.ts.map +1 -0
- package/dist/runtime/hmrProtocol.js +15 -0
- package/dist/runtime/hmrProtocolPublic.d.ts +2 -0
- package/dist/runtime/hmrProtocolPublic.d.ts.map +1 -0
- package/dist/runtime/hmrProtocolPublic.js +1 -0
- package/dist/runtime/runtime.d.ts +10 -7
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +116 -114
- package/dist/runtime/subscription.d.ts +5 -5
- package/dist/runtime/subscription.d.ts.map +1 -1
- package/dist/runtime/urlRequest.d.ts +15 -15
- package/dist/runtime/urlRequest.d.ts.map +1 -1
- package/dist/runtime/urlRequest.js +1 -1
- package/dist/schema/index.d.ts +3 -3
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +10 -4
- package/dist/task/dom.js +1 -1
- package/dist/task/elementMovement.js +1 -1
- package/dist/task/error.d.ts +2 -2
- package/dist/task/inert.d.ts.map +1 -1
- package/dist/task/inert.js +4 -7
- package/dist/task/time.d.ts +1 -1
- package/dist/task/time.js +1 -1
- package/dist/task/timing.d.ts +1 -1
- package/dist/task/timing.d.ts.map +1 -1
- package/dist/task/timing.js +2 -2
- package/dist/test/apps/bubbling.d.ts +3 -3
- package/dist/test/apps/bubbling.d.ts.map +1 -1
- package/dist/test/apps/bubbling.js +1 -1
- package/dist/test/apps/counter.d.ts +6 -6
- package/dist/test/apps/counter.d.ts.map +1 -1
- package/dist/test/apps/counter.js +7 -1
- package/dist/test/apps/disabledButton.d.ts +11 -11
- package/dist/test/apps/disabledButton.d.ts.map +1 -1
- package/dist/test/apps/disabledButton.js +1 -1
- package/dist/test/apps/fileUpload.d.ts +4 -4
- package/dist/test/apps/fileUpload.d.ts.map +1 -1
- package/dist/test/apps/fileUpload.js +1 -1
- package/dist/test/apps/formChild.d.ts +16 -16
- package/dist/test/apps/formChild.d.ts.map +1 -1
- package/dist/test/apps/formChild.js +9 -4
- package/dist/test/apps/interactions.d.ts +8 -8
- package/dist/test/apps/interactions.d.ts.map +1 -1
- package/dist/test/apps/interactions.js +8 -1
- package/dist/test/apps/keypress.d.ts +7 -7
- package/dist/test/apps/keypress.d.ts.map +1 -1
- package/dist/test/apps/keypress.js +1 -1
- package/dist/test/apps/login.d.ts +14 -14
- package/dist/test/apps/login.d.ts.map +1 -1
- package/dist/test/apps/login.js +9 -2
- package/dist/test/apps/logoutButton.d.ts +3 -3
- package/dist/test/apps/logoutButton.d.ts.map +1 -1
- package/dist/test/apps/logoutButton.js +2 -2
- package/dist/test/apps/multiRole.d.ts +2 -2
- package/dist/test/apps/multiRole.d.ts.map +1 -1
- package/dist/test/apps/multiRole.js +1 -1
- package/dist/test/apps/pointer.d.ts +6 -6
- package/dist/test/apps/pointer.d.ts.map +1 -1
- package/dist/test/apps/pointer.js +1 -1
- package/dist/test/apps/resumeUpload.d.ts +8 -8
- package/dist/test/apps/resumeUpload.d.ts.map +1 -1
- package/dist/test/apps/resumeUpload.js +12 -5
- package/dist/test/internal.js +10 -10
- package/dist/test/matchers.js +1 -1
- package/dist/test/query.d.ts.map +1 -1
- package/dist/test/query.js +13 -13
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +3 -3
- package/dist/test/story.js +1 -1
- package/dist/ui/animation/schema.d.ts +5 -5
- package/dist/ui/animation/schema.d.ts.map +1 -1
- package/dist/ui/animation/schema.js +9 -3
- package/dist/ui/calendar/index.d.ts +77 -77
- package/dist/ui/calendar/index.d.ts.map +1 -1
- package/dist/ui/calendar/index.js +26 -11
- package/dist/ui/checkbox/index.d.ts +2 -2
- package/dist/ui/combobox/multi.d.ts +38 -42
- package/dist/ui/combobox/multi.d.ts.map +1 -1
- package/dist/ui/combobox/multi.js +4 -1
- package/dist/ui/combobox/shared.d.ts +31 -31
- package/dist/ui/combobox/shared.d.ts.map +1 -1
- package/dist/ui/combobox/shared.js +34 -12
- package/dist/ui/combobox/single.d.ts +39 -43
- package/dist/ui/combobox/single.d.ts.map +1 -1
- package/dist/ui/combobox/single.js +7 -6
- package/dist/ui/datePicker/index.d.ts +86 -86
- package/dist/ui/datePicker/index.d.ts.map +1 -1
- package/dist/ui/datePicker/index.js +10 -3
- package/dist/ui/dialog/index.d.ts +8 -8
- package/dist/ui/dialog/index.d.ts.map +1 -1
- package/dist/ui/dialog/index.js +9 -3
- package/dist/ui/disclosure/index.d.ts +2 -2
- package/dist/ui/disclosure/index.d.ts.map +1 -1
- package/dist/ui/disclosure/index.js +1 -1
- package/dist/ui/dragAndDrop/index.d.ts +76 -76
- package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/index.js +47 -29
- package/dist/ui/fileDrop/index.d.ts +8 -8
- package/dist/ui/fileDrop/index.d.ts.map +1 -1
- package/dist/ui/fileDrop/index.js +7 -2
- package/dist/ui/listbox/multi.d.ts +36 -40
- package/dist/ui/listbox/multi.d.ts.map +1 -1
- package/dist/ui/listbox/multi.js +4 -1
- package/dist/ui/listbox/shared.d.ts +32 -32
- package/dist/ui/listbox/shared.d.ts.map +1 -1
- package/dist/ui/listbox/shared.js +36 -11
- package/dist/ui/listbox/single.d.ts +36 -40
- package/dist/ui/listbox/single.d.ts.map +1 -1
- package/dist/ui/listbox/single.js +5 -2
- package/dist/ui/menu/index.d.ts +40 -40
- package/dist/ui/menu/index.d.ts.map +1 -1
- package/dist/ui/menu/index.js +38 -11
- package/dist/ui/popover/index.d.ts +12 -12
- package/dist/ui/popover/index.d.ts.map +1 -1
- package/dist/ui/popover/index.js +17 -2
- package/dist/ui/radioGroup/index.d.ts +6 -6
- package/dist/ui/radioGroup/index.d.ts.map +1 -1
- package/dist/ui/radioGroup/index.js +5 -5
- package/dist/ui/slider/index.d.ts +26 -26
- package/dist/ui/slider/index.d.ts.map +1 -1
- package/dist/ui/slider/index.js +30 -16
- package/dist/ui/switch/index.d.ts +2 -2
- package/dist/ui/tabs/index.d.ts +8 -8
- package/dist/ui/tabs/index.d.ts.map +1 -1
- package/dist/ui/tabs/index.js +3 -3
- package/dist/ui/toast/index.d.ts +75 -75
- package/dist/ui/toast/index.d.ts.map +1 -1
- package/dist/ui/toast/index.js +1 -1
- package/dist/ui/toast/schema.d.ts +63 -63
- package/dist/ui/toast/schema.d.ts.map +1 -1
- package/dist/ui/toast/schema.js +19 -4
- package/dist/ui/toast/update.d.ts +67 -67
- package/dist/ui/toast/update.d.ts.map +1 -1
- package/dist/ui/toast/update.js +2 -2
- package/dist/ui/tooltip/index.d.ts +15 -15
- package/dist/ui/tooltip/index.d.ts.map +1 -1
- package/dist/ui/tooltip/index.js +14 -4
- package/dist/ui/virtualList/index.d.ts +16 -16
- package/dist/ui/virtualList/index.d.ts.map +1 -1
- package/dist/ui/virtualList/index.js +46 -42
- package/dist/url/index.d.ts +8 -8
- package/dist/url/index.d.ts.map +1 -1
- package/dist/url/index.js +14 -14
- package/package.json +12 -8
|
@@ -12,7 +12,7 @@ export const SerializedEntry = S.Struct({
|
|
|
12
12
|
changedPaths: S.Array(S.String),
|
|
13
13
|
affectedPaths: S.Array(S.String),
|
|
14
14
|
submodelPath: S.Array(S.String),
|
|
15
|
-
maybeLeafTag: S.
|
|
15
|
+
maybeLeafTag: S.OptionFromNullOr(S.String),
|
|
16
16
|
});
|
|
17
17
|
/** Metadata about a single keyframe. The index identifies the point in history where the runtime can replay back to. */
|
|
18
18
|
export const KeyframeInfo = S.Struct({
|
|
@@ -27,19 +27,19 @@ export const RuntimeInfo = S.Struct({
|
|
|
27
27
|
// REQUEST
|
|
28
28
|
/** Request the current Model snapshot, optionally narrowed to a path and/or expanded. */
|
|
29
29
|
export const RequestGetModel = ts('RequestGetModel', {
|
|
30
|
-
maybePath: S.
|
|
30
|
+
maybePath: S.OptionFromNullOr(S.String),
|
|
31
31
|
expand: S.Boolean,
|
|
32
32
|
});
|
|
33
33
|
/** Request a historical Model snapshot at an absolute history index, optionally narrowed to a path and/or expanded. Use `index: -1` for the initial Model. */
|
|
34
34
|
export const RequestGetModelAt = ts('RequestGetModelAt', {
|
|
35
35
|
index: S.Number,
|
|
36
|
-
maybePath: S.
|
|
36
|
+
maybePath: S.OptionFromNullOr(S.String),
|
|
37
37
|
expand: S.Boolean,
|
|
38
38
|
});
|
|
39
39
|
/** Request recent history entries, optionally starting from a given index. */
|
|
40
40
|
export const RequestListMessages = ts('RequestListMessages', {
|
|
41
41
|
limit: S.Number,
|
|
42
|
-
maybeSinceIndex: S.
|
|
42
|
+
maybeSinceIndex: S.OptionFromNullOr(S.Number),
|
|
43
43
|
});
|
|
44
44
|
/** Request a single history entry by index. To inspect the Model around the entry, call `RequestGetModelAt` with `index - 1` (before) and `index` (after). */
|
|
45
45
|
export const RequestGetMessage = ts('RequestGetMessage', {
|
|
@@ -64,7 +64,19 @@ export const RequestDispatchMessage = ts('RequestDispatchMessage', {
|
|
|
64
64
|
/** Request the list of currently connected browser runtimes. Handled by the Vite plugin, not forwarded to a runtime. */
|
|
65
65
|
export const RequestListRuntimes = ts('RequestListRuntimes');
|
|
66
66
|
/** A request from the MCP server. RequestListRuntimes is handled at the Vite plugin layer; all other requests are routed to a browser runtime. */
|
|
67
|
-
export const Request = S.Union(
|
|
67
|
+
export const Request = S.Union([
|
|
68
|
+
RequestGetModel,
|
|
69
|
+
RequestGetModelAt,
|
|
70
|
+
RequestListMessages,
|
|
71
|
+
RequestGetMessage,
|
|
72
|
+
RequestListKeyframes,
|
|
73
|
+
RequestReplayToKeyframe,
|
|
74
|
+
RequestResume,
|
|
75
|
+
RequestDispatchMessage,
|
|
76
|
+
RequestListRuntimes,
|
|
77
|
+
RequestGetInit,
|
|
78
|
+
RequestGetRuntimeState,
|
|
79
|
+
]);
|
|
68
80
|
// RESPONSE
|
|
69
81
|
/** Response carrying a Model snapshot. The `value` is the resolved subtree at `atPath` (or the whole Model when no path was supplied). When `summarized` is true, large arrays/records/strings have been collapsed to `_summary` placeholders to keep payloads small for AI agents; pass `expand: true` on the Request to receive the literal value. */
|
|
70
82
|
export const ResponseModel = ts('ResponseModel', {
|
|
@@ -75,7 +87,7 @@ export const ResponseModel = ts('ResponseModel', {
|
|
|
75
87
|
/** Response carrying a page of history entries. `maybeNextIndex` is `Some` when more entries are available beyond this page (pass it as `RequestListMessages.maybeSinceIndex` to fetch the next page) and `None` when this page reaches the current end of history. */
|
|
76
88
|
export const ResponseMessages = ts('ResponseMessages', {
|
|
77
89
|
entries: S.Array(SerializedEntry),
|
|
78
|
-
maybeNextIndex: S.
|
|
90
|
+
maybeNextIndex: S.OptionFromNullOr(S.Number),
|
|
79
91
|
});
|
|
80
92
|
/** Response carrying a single history entry. Model snapshots are not included; use `RequestGetModelAt` with `index - 1` and `index` to inspect Model state around the entry. */
|
|
81
93
|
export const ResponseMessage = ts('ResponseMessage', {
|
|
@@ -101,7 +113,7 @@ export const ResponseRuntimes = ts('ResponseRuntimes', {
|
|
|
101
113
|
});
|
|
102
114
|
/** Response carrying the recorded init data. `maybeModel` is `None` until the runtime has finished its first render and recorded init; once set it stays set for the rest of the runtime's life. `commandNames` lists the Commands returned from the application's `init` function in the order they were produced. */
|
|
103
115
|
export const ResponseInit = ts('ResponseInit', {
|
|
104
|
-
maybeModel: S.
|
|
116
|
+
maybeModel: S.OptionFromNullOr(S.Unknown),
|
|
105
117
|
commandNames: S.Array(S.String),
|
|
106
118
|
});
|
|
107
119
|
/** Response carrying a snapshot of the runtime's DevTools state. `currentIndex` is the absolute index of the most recently recorded Message, or -1 when no Messages have been recorded yet. `startIndex` is the earliest absolute index still retained in the rolling buffer (older entries are evicted past `maxEntries`). `totalEntries` is the number of retained entries. `isPaused` is true while the runtime is paused at a replayed snapshot; `maybePausedAtIndex` is `Some(index)` then and `None` otherwise. `hasInitModel` is true once the runtime has finished initialising. */
|
|
@@ -110,7 +122,7 @@ export const ResponseRuntimeState = ts('ResponseRuntimeState', {
|
|
|
110
122
|
startIndex: S.Number,
|
|
111
123
|
totalEntries: S.Number,
|
|
112
124
|
isPaused: S.Boolean,
|
|
113
|
-
maybePausedAtIndex: S.
|
|
125
|
+
maybePausedAtIndex: S.OptionFromNullOr(S.Number),
|
|
114
126
|
hasInitModel: S.Boolean,
|
|
115
127
|
});
|
|
116
128
|
/** Response carrying an error reason for a failed Request. */
|
|
@@ -118,7 +130,19 @@ export const ResponseError = ts('ResponseError', {
|
|
|
118
130
|
reason: S.String,
|
|
119
131
|
});
|
|
120
132
|
/** A response replying to a Request. */
|
|
121
|
-
export const Response = S.Union(
|
|
133
|
+
export const Response = S.Union([
|
|
134
|
+
ResponseModel,
|
|
135
|
+
ResponseMessages,
|
|
136
|
+
ResponseMessage,
|
|
137
|
+
ResponseKeyframes,
|
|
138
|
+
ResponseReplayed,
|
|
139
|
+
ResponseResumed,
|
|
140
|
+
ResponseDispatched,
|
|
141
|
+
ResponseRuntimes,
|
|
142
|
+
ResponseInit,
|
|
143
|
+
ResponseRuntimeState,
|
|
144
|
+
ResponseError,
|
|
145
|
+
]);
|
|
122
146
|
// EVENT
|
|
123
147
|
/** A new browser runtime connected. */
|
|
124
148
|
export const EventConnected = ts('EventConnected', {
|
|
@@ -129,12 +153,12 @@ export const EventDisconnected = ts('EventDisconnected', {
|
|
|
129
153
|
connectionId: S.String,
|
|
130
154
|
});
|
|
131
155
|
/** A runtime lifecycle event used by the Vite plugin to track which browser tabs are connected. Not forwarded to MCP clients. */
|
|
132
|
-
export const Event = S.Union(EventConnected, EventDisconnected);
|
|
156
|
+
export const Event = S.Union([EventConnected, EventDisconnected]);
|
|
133
157
|
// FRAME
|
|
134
158
|
/** A wire frame carrying a Request from the MCP server. The id is opaque, used only by the MCP server to correlate the matching Response. The maybeConnectionId routes the request to a specific runtime when present. */
|
|
135
159
|
export const RequestFrame = S.Struct({
|
|
136
160
|
id: S.String,
|
|
137
|
-
maybeConnectionId: S.
|
|
161
|
+
maybeConnectionId: S.OptionFromNullOr(S.String),
|
|
138
162
|
request: Request,
|
|
139
163
|
});
|
|
140
164
|
/** A wire frame carrying a Response, correlated to a Request by id. */
|
|
@@ -144,6 +168,6 @@ export const ResponseFrame = S.Struct({
|
|
|
144
168
|
});
|
|
145
169
|
/** A wire frame carrying a runtime lifecycle event from the bridge to the Vite plugin. */
|
|
146
170
|
export const EventFrame = S.Struct({
|
|
147
|
-
maybeConnectionId: S.
|
|
171
|
+
maybeConnectionId: S.OptionFromNullOr(S.String),
|
|
148
172
|
event: Event,
|
|
149
173
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/devTools/serialize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/devTools/serialize.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAiBjD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,YAAY,EACnB,OAAO,MAAM,KACZ,eAkBF,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array as Array_, Function,
|
|
1
|
+
import { Array as Array_, Function, Match as M, Predicate, Record, } from 'effect';
|
|
2
2
|
import { extractSubmodelInfo } from './submodelPath.js';
|
|
3
3
|
/**
|
|
4
4
|
* Convert DOM-class instances (File, Blob, Date, URL) to plain-object
|
|
@@ -16,7 +16,7 @@ export const toInspectableValue = (value) => M.value(value).pipe(M.when(M.instan
|
|
|
16
16
|
})), M.when(M.instanceOf(Blob), blob => ({
|
|
17
17
|
size: blob.size,
|
|
18
18
|
type: blob.type,
|
|
19
|
-
})), M.when(M.instanceOf(Date), date => date.toISOString()), M.when(M.instanceOf(URL), ({ href }) => href), M.when(Array.isArray, Array_.map(toInspectableValue)), M.when(Predicate.
|
|
19
|
+
})), M.when(M.instanceOf(Date), date => date.toISOString()), M.when(M.instanceOf(URL), ({ href }) => href), M.when(Array.isArray, Array_.map(toInspectableValue)), M.when(Predicate.isObject, Record.map(toInspectableValue)), M.orElse(Function.identity));
|
|
20
20
|
/**
|
|
21
21
|
* Convert a `HistoryEntry` plus its absolute index into the wire-friendly
|
|
22
22
|
* `SerializedEntry` shape. Flattens the diff's `HashSet` path collections to
|
|
@@ -32,8 +32,8 @@ export const toSerializedEntry = (entry, index) => {
|
|
|
32
32
|
commandNames: entry.commandNames,
|
|
33
33
|
timestamp: entry.timestamp,
|
|
34
34
|
isModelChanged: entry.isModelChanged,
|
|
35
|
-
changedPaths:
|
|
36
|
-
affectedPaths:
|
|
35
|
+
changedPaths: Array_.fromIterable(entry.diff.changedPaths),
|
|
36
|
+
affectedPaths: Array_.fromIterable(entry.diff.affectedPaths),
|
|
37
37
|
submodelPath,
|
|
38
38
|
maybeLeafTag,
|
|
39
39
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,OAAO,EACP,OAAO,EACP,MAAM,EAIN,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAEf,eAAO,MAAM,UAAU,KAAK,CAAA;AAM5B,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;CACvC,CAAC,CAAA;AAEF,eAAO,MAAM,SAAS,EAAE,UAGvB,CAAA;AAKD,eAAO,MAAM,WAAW,GACtB,UAAU,OAAO,EACjB,SAAS,OAAO,KACf,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"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"}
|
package/dist/devTools/store.js
CHANGED
|
@@ -20,8 +20,7 @@ export const computeDiff = (previous, current) => {
|
|
|
20
20
|
if (Array.isArray(curr) && Array.isArray(prev)) {
|
|
21
21
|
walkArray(prev, curr, path);
|
|
22
22
|
}
|
|
23
|
-
else if (Predicate.
|
|
24
|
-
Predicate.isReadonlyRecord(prev)) {
|
|
23
|
+
else if (Predicate.isObject(curr) && Predicate.isObject(prev)) {
|
|
25
24
|
walkObject(prev, curr, path);
|
|
26
25
|
}
|
|
27
26
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Option } from 'effect';
|
|
2
2
|
export declare const GOT_MESSAGE_PATTERN: RegExp;
|
|
3
|
-
export declare const isTagged: (
|
|
3
|
+
export declare const isTagged: <I>(input: I) => input is I & {
|
|
4
4
|
readonly _tag: string;
|
|
5
5
|
};
|
|
6
6
|
/** Submodel chain information extracted from a recorded Message. */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Schema as S } from 'effect';
|
|
2
|
-
declare const PathResolution: S.Union<[import("../schema/index.js").CallableTaggedStruct<"Found", {
|
|
3
|
-
value:
|
|
4
|
-
atPath:
|
|
2
|
+
declare const PathResolution: S.Union<readonly [import("../schema/index.js").CallableTaggedStruct<"Found", {
|
|
3
|
+
value: S.Unknown;
|
|
4
|
+
atPath: S.String;
|
|
5
5
|
}>, import("../schema/index.js").CallableTaggedStruct<"NotFound", {
|
|
6
|
-
failedAt:
|
|
7
|
-
reason:
|
|
8
|
-
availableKeys: S
|
|
6
|
+
failedAt: S.String;
|
|
7
|
+
reason: S.String;
|
|
8
|
+
availableKeys: S.$Array<S.String>;
|
|
9
9
|
}>]>;
|
|
10
10
|
/**
|
|
11
11
|
* Result of resolving a dot-string path against a Model snapshot.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../src/devTools/summarize.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,MAAM,IAAI,CAAC,EACZ,MAAM,QAAQ,CAAA;AAwBf,QAAA,MAAM,cAAc;;;;;;;
|
|
1
|
+
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../src/devTools/summarize.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,MAAM,IAAI,CAAC,EACZ,MAAM,QAAQ,CAAA;AAwBf,QAAA,MAAM,cAAc;;;;;;;IAA6B,CAAA;AAEjD;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAiCvD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAG,cAmCzD,CAAA;AAyDD;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,OAAgC,CAAA;AAYhF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,KACtD,MAIC,CAAA"}
|
|
@@ -16,12 +16,12 @@ const NotFound = ts('NotFound', {
|
|
|
16
16
|
reason: S.String,
|
|
17
17
|
availableKeys: S.Array(S.String),
|
|
18
18
|
});
|
|
19
|
-
const PathResolution = S.Union(Found, NotFound);
|
|
20
|
-
const isExpandable = (value) => Predicate.
|
|
21
|
-
const keysOf = (value) => M.value(value).pipe(M.when(Array.isArray, items => Array_.makeBy(items.length, index => index.toString())), M.when(Predicate.
|
|
19
|
+
const PathResolution = S.Union([Found, NotFound]);
|
|
20
|
+
const isExpandable = (value) => Predicate.isObject(value) || Array.isArray(value);
|
|
21
|
+
const keysOf = (value) => M.value(value).pipe(M.when(Array.isArray, items => Array_.makeBy(items.length, index => index.toString())), M.when(Predicate.isObject, Record.keys), M.orElse(() => []));
|
|
22
22
|
const segmentsOf = (path) => path === ROOT ? [] : path.split(PATH_SEPARATOR).slice(1);
|
|
23
23
|
const isRootAnchored = (path) => path === ROOT || path.startsWith(`${ROOT}${PATH_SEPARATOR}`);
|
|
24
|
-
const descend = (parent, segment) => M.value(parent).pipe(M.when(Array.isArray, array => Option.liftPredicate(Number(segment), Number.isInteger).pipe(Option.flatMap(index => Array_.get(array, index)))), M.when(Predicate.
|
|
24
|
+
const descend = (parent, segment) => M.value(parent).pipe(M.when(Array.isArray, array => Option.liftPredicate(Number(segment), Number.isInteger).pipe(Option.flatMap(index => Array_.get(array, index)))), M.when(Predicate.isObject, record => Record.get(record, segment)), M.orElse(() => Option.none()));
|
|
25
25
|
/**
|
|
26
26
|
* Walk a dot-string path against a Model snapshot. Returns the resolved value
|
|
27
27
|
* on success, or a structured `NotFound` describing the deepest segment that
|
|
@@ -86,7 +86,7 @@ const summarizeRecord = (value, depth) => {
|
|
|
86
86
|
}
|
|
87
87
|
return Record.map(value, child => summarizeAt(child, depth + 1));
|
|
88
88
|
};
|
|
89
|
-
const summarizeAt = (value, depth) => M.value(value).pipe(M.when(Predicate.isString, truncateString), M.when(Array.isArray, items => summarizeArray(items, depth)), M.when(Predicate.
|
|
89
|
+
const summarizeAt = (value, depth) => M.value(value).pipe(M.when(Predicate.isString, truncateString), M.when(Array.isArray, items => summarizeArray(items, depth)), M.when(Predicate.isObject, record => summarizeRecord(record, depth)), M.orElse(Function.identity));
|
|
90
90
|
/**
|
|
91
91
|
* Apply structural summarization rules to a value:
|
|
92
92
|
* - Arrays collapse to `{ _summary, length, sample: [head, last] }` at every depth.
|
|
@@ -99,7 +99,7 @@ const summarizeAt = (value, depth) => M.value(value).pipe(M.when(Predicate.isStr
|
|
|
99
99
|
*/
|
|
100
100
|
export const summarizeValue = (value) => summarizeAt(value, 0);
|
|
101
101
|
// FORMAT
|
|
102
|
-
const formatAvailableKeys = (keys) => OptionExt.when(Array_.
|
|
102
|
+
const formatAvailableKeys = (keys) => OptionExt.when(Array_.isReadonlyArrayNonEmpty(keys), `Available keys: ${keys.join(', ')}.`);
|
|
103
103
|
/**
|
|
104
104
|
* Format a `NotFound` resolution as a single human-readable line for the
|
|
105
105
|
* `ResponseError.reason` channel. Includes the available keys at the failure
|
|
@@ -19,6 +19,6 @@ type Hot = NonNullable<ImportMeta['hot']>;
|
|
|
19
19
|
* Production-safe: callers must check `import.meta.hot` is defined before
|
|
20
20
|
* invoking this. The function assumes a live HMR connection.
|
|
21
21
|
*/
|
|
22
|
-
export declare const startWebSocketBridge: (store: DevToolsStore, hot: Hot, dispatch: (message: unknown) => Effect.Effect<void>, maybeMessageSchema: Option.Option<S.
|
|
22
|
+
export declare const startWebSocketBridge: (store: DevToolsStore, hot: Hot, dispatch: (message: unknown) => Effect.Effect<void>, maybeMessageSchema: Option.Option<S.Codec<any, any>>) => Effect.Effect<void>;
|
|
23
23
|
export {};
|
|
24
24
|
//# sourceMappingURL=webSocketBridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webSocketBridge.d.ts","sourceRoot":"","sources":["../../src/devTools/webSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAIN,MAAM,
|
|
1
|
+
{"version":3,"file":"webSocketBridge.d.ts","sourceRoot":"","sources":["../../src/devTools/webSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAIN,MAAM,EAEN,MAAM,IAAI,CAAC,EAGZ,MAAM,QAAQ,CAAA;AA0Bf,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,YAAY,CAAA;AAQ3D,KAAK,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;AAczC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,aAAa,EACpB,KAAK,GAAG,EACR,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EACnD,oBAAoB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KACnD,MAAM,CAAC,MAAM,CAAC,IAAI,CA+EjB,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Array, Cause, Effect,
|
|
1
|
+
import { Array, Cause, Effect, Exit, HashMap, Match, Option, Order, Schema as S, SubscriptionRef, pipe, } from 'effect';
|
|
2
2
|
import { OptionExt } from '../effectExtensions/index.js';
|
|
3
|
-
import { EventConnected, EventDisconnected, KeyframeInfo, RequestFrame, ResponseDispatched, ResponseError, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimeState, RuntimeInfo, } from './protocol.js';
|
|
3
|
+
import { EventConnected, EventDisconnected, EventFrame, KeyframeInfo, RequestFrame, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimeState, RuntimeInfo, } from './protocol.js';
|
|
4
4
|
import { toInspectableValue, toSerializedEntry } from './serialize.js';
|
|
5
5
|
import { INIT_INDEX } from './store.js';
|
|
6
6
|
import { formatPathNotFound, resolvePath, summarizeValue, } from './summarize.js';
|
|
@@ -29,16 +29,17 @@ const currentAbsoluteIndex = (entriesLength, startIndex) => (entriesLength === 0
|
|
|
29
29
|
*/
|
|
30
30
|
export const startWebSocketBridge = (store, hot, dispatch, maybeMessageSchema) => Effect.gen(function* () {
|
|
31
31
|
const connectionId = generateConnectionId();
|
|
32
|
-
const
|
|
32
|
+
const capturedContext = yield* Effect.context();
|
|
33
|
+
const encodeEventFrame = S.encodeUnknownSync(EventFrame);
|
|
34
|
+
const encodeResponseFrame = S.encodeUnknownSync(ResponseFrame);
|
|
33
35
|
const sendEvent = (event) => {
|
|
34
|
-
hot.send(EVENT_CHANNEL, {
|
|
36
|
+
hot.send(EVENT_CHANNEL, encodeEventFrame({
|
|
35
37
|
maybeConnectionId: Option.some(connectionId),
|
|
36
38
|
event,
|
|
37
|
-
});
|
|
39
|
+
}));
|
|
38
40
|
};
|
|
39
41
|
const sendResponse = (id, response) => {
|
|
40
|
-
|
|
41
|
-
hot.send(RESPONSE_CHANNEL, frame);
|
|
42
|
+
hot.send(RESPONSE_CHANNEL, encodeResponseFrame({ id, response }));
|
|
42
43
|
};
|
|
43
44
|
sendEvent(EventConnected({
|
|
44
45
|
runtime: RuntimeInfo.make({
|
|
@@ -52,17 +53,17 @@ export const startWebSocketBridge = (store, hot, dispatch, maybeMessageSchema) =
|
|
|
52
53
|
sendResponse(id, response);
|
|
53
54
|
});
|
|
54
55
|
const handleRequestFrame = (frame) => {
|
|
55
|
-
const decoded = S.
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const decoded = S.decodeUnknownExit(RequestFrame)(frame);
|
|
57
|
+
Exit.match(decoded, {
|
|
58
|
+
onFailure: error => {
|
|
58
59
|
console.warn('[foldkit:devTools] malformed request frame', error);
|
|
59
60
|
},
|
|
60
|
-
|
|
61
|
+
onSuccess: ({ id, maybeConnectionId, request }) => {
|
|
61
62
|
const isForUs = Option.exists(maybeConnectionId, targetId => targetId === connectionId);
|
|
62
63
|
if (!isForUs) {
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
+
Effect.runForkWith(capturedContext)(handleRequest(id, request));
|
|
66
67
|
},
|
|
67
68
|
});
|
|
68
69
|
};
|
|
@@ -90,7 +91,7 @@ const readModelResponse = (store, index, maybePath, expand) => Effect.gen(functi
|
|
|
90
91
|
const model = yield* store.getModelAtIndex(index);
|
|
91
92
|
const path = Option.getOrElse(maybePath, () => 'root');
|
|
92
93
|
return presentResolution(resolvePath(toInspectableValue(model), path), expand);
|
|
93
|
-
}).pipe(Effect.
|
|
94
|
+
}).pipe(Effect.catchCause(cause => Effect.succeed(ResponseError({
|
|
94
95
|
reason: `Failed to read Model at index ${index}: ${Cause.pretty(cause)}`,
|
|
95
96
|
}))));
|
|
96
97
|
const dispatchRequest = (store, dispatch, maybeMessageSchema, request) => Match.value(request).pipe(Match.tagsExhaustive({
|
|
@@ -125,7 +126,7 @@ const dispatchRequest = (store, dispatch, maybeMessageSchema, request) => Match.
|
|
|
125
126
|
}),
|
|
126
127
|
RequestListKeyframes: () => Effect.gen(function* () {
|
|
127
128
|
const state = yield* SubscriptionRef.get(store.stateRef);
|
|
128
|
-
const sortedKeyframeIndices = pipe(state.keyframes, HashMap.keys, Array.fromIterable, Array.sort(Order.
|
|
129
|
+
const sortedKeyframeIndices = pipe(state.keyframes, HashMap.keys, Array.fromIterable, Array.sort(Order.Number));
|
|
129
130
|
const indicesWithInit = Option.match(state.maybeInitModel, {
|
|
130
131
|
onNone: () => sortedKeyframeIndices,
|
|
131
132
|
onSome: () => [INIT_INDEX, ...sortedKeyframeIndices],
|
|
@@ -137,13 +138,13 @@ const dispatchRequest = (store, dispatch, maybeMessageSchema, request) => Match.
|
|
|
137
138
|
yield* store.jumpTo(keyframeIndex);
|
|
138
139
|
const model = yield* store.getModelAtIndex(keyframeIndex);
|
|
139
140
|
return ResponseReplayed({ model: toInspectableValue(model) });
|
|
140
|
-
}), Effect.
|
|
141
|
+
}), Effect.catchCause(cause => Effect.succeed(ResponseError({
|
|
141
142
|
reason: `Failed to replay to keyframe ${keyframeIndex}: ${Cause.pretty(cause)}`,
|
|
142
143
|
})))),
|
|
143
144
|
RequestResume: () => Effect.gen(function* () {
|
|
144
145
|
yield* store.resume;
|
|
145
146
|
return ResponseResumed();
|
|
146
|
-
}).pipe(Effect.
|
|
147
|
+
}).pipe(Effect.catchCause(cause => Effect.succeed(ResponseError({
|
|
147
148
|
reason: `Failed to resume: ${Cause.pretty(cause)}`,
|
|
148
149
|
})))),
|
|
149
150
|
RequestDispatchMessage: ({ message }) => Option.match(maybeMessageSchema, {
|
|
@@ -151,12 +152,12 @@ const dispatchRequest = (store, dispatch, maybeMessageSchema, request) => Match.
|
|
|
151
152
|
reason: 'Cannot dispatch: DevToolsConfig.Message not configured. Pass your Message Schema to enable dispatch.',
|
|
152
153
|
})),
|
|
153
154
|
onSome: messageSchema => Effect.gen(function* () {
|
|
154
|
-
const decodedMessage = yield* S.
|
|
155
|
+
const decodedMessage = yield* S.decodeUnknownEffect(messageSchema)(message);
|
|
155
156
|
const stateBefore = yield* SubscriptionRef.get(store.stateRef);
|
|
156
157
|
const acceptedAtIndex = stateBefore.startIndex + stateBefore.entries.length;
|
|
157
158
|
yield* dispatch(decodedMessage);
|
|
158
159
|
return ResponseDispatched({ acceptedAtIndex });
|
|
159
|
-
}).pipe(Effect.
|
|
160
|
+
}).pipe(Effect.catch(error => Effect.succeed(ResponseError({
|
|
160
161
|
reason: `Invalid Message: ${error instanceof Error ? error.message : String(error)}\n\nReceived (typeof ${typeof message}): ${JSON.stringify(message)}`,
|
|
161
162
|
})))),
|
|
162
163
|
}),
|
|
@@ -6,31 +6,31 @@ export type Rule = readonly [Predicate.Predicate<string>, RuleMessage];
|
|
|
6
6
|
export declare const resolveMessage: (message: RuleMessage, value: string) => string;
|
|
7
7
|
/** The `NotValidated` state: user hasn't interacted yet. */
|
|
8
8
|
export declare const NotValidated: import("../schema/index.js").CallableTaggedStruct<"NotValidated", {
|
|
9
|
-
value:
|
|
9
|
+
value: S.String;
|
|
10
10
|
}>;
|
|
11
11
|
/** The `Validating` state: async validation is in flight. */
|
|
12
12
|
export declare const Validating: import("../schema/index.js").CallableTaggedStruct<"Validating", {
|
|
13
|
-
value:
|
|
13
|
+
value: S.String;
|
|
14
14
|
}>;
|
|
15
15
|
/** The `Valid` state: every rule passed. */
|
|
16
16
|
export declare const Valid: import("../schema/index.js").CallableTaggedStruct<"Valid", {
|
|
17
|
-
value:
|
|
17
|
+
value: S.String;
|
|
18
18
|
}>;
|
|
19
19
|
/** The `Invalid` state: one or more rules failed. Carries a non-empty `errors` array. */
|
|
20
20
|
export declare const Invalid: import("../schema/index.js").CallableTaggedStruct<"Invalid", {
|
|
21
|
-
value:
|
|
22
|
-
errors: S.NonEmptyArray<
|
|
21
|
+
value: S.String;
|
|
22
|
+
errors: S.NonEmptyArray<S.String>;
|
|
23
23
|
}>;
|
|
24
24
|
/** The four-state union that represents a field's value in the Model. */
|
|
25
|
-
export declare const Field: S.Union<[import("../schema/index.js").CallableTaggedStruct<"NotValidated", {
|
|
26
|
-
value:
|
|
25
|
+
export declare const Field: S.Union<readonly [import("../schema/index.js").CallableTaggedStruct<"NotValidated", {
|
|
26
|
+
value: S.String;
|
|
27
27
|
}>, import("../schema/index.js").CallableTaggedStruct<"Validating", {
|
|
28
|
-
value:
|
|
28
|
+
value: S.String;
|
|
29
29
|
}>, import("../schema/index.js").CallableTaggedStruct<"Valid", {
|
|
30
|
-
value:
|
|
30
|
+
value: S.String;
|
|
31
31
|
}>, import("../schema/index.js").CallableTaggedStruct<"Invalid", {
|
|
32
|
-
value:
|
|
33
|
-
errors: S.NonEmptyArray<
|
|
32
|
+
value: S.String;
|
|
33
|
+
errors: S.NonEmptyArray<S.String>;
|
|
34
34
|
}>]>;
|
|
35
35
|
export type Field = typeof Field.Type;
|
|
36
36
|
/** A field's validation rules: the required message (if any), the list of rules,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fieldValidation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EACN,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fieldValidation/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Array, Number as Number_, Option, Schema as S, String, flow, pipe, } from 'effect';
|
|
2
|
-
import { OptionExt } from '../effectExtensions/index.js';
|
|
1
|
+
import { Array, Number as Number_, Option, Result, Schema as S, String, flow, pipe, } from 'effect';
|
|
3
2
|
import { ts } from '../schema/index.js';
|
|
4
3
|
export const resolveMessage = (message, value) => typeof message === 'string' ? message : message(value);
|
|
5
4
|
// STATE
|
|
@@ -15,9 +14,9 @@ export const Invalid = ts('Invalid', {
|
|
|
15
14
|
errors: S.NonEmptyArray(S.String),
|
|
16
15
|
});
|
|
17
16
|
/** The four-state union that represents a field's value in the Model. */
|
|
18
|
-
export const Field = S.Union(NotValidated, Validating, Valid, Invalid);
|
|
17
|
+
export const Field = S.Union([NotValidated, Validating, Valid, Invalid]);
|
|
19
18
|
export const makeRules = (options = {}) => ({
|
|
20
|
-
requiredMessage: Option.
|
|
19
|
+
requiredMessage: Option.fromNullishOr(options.required),
|
|
21
20
|
rules: options.rules ?? [],
|
|
22
21
|
isEmpty: options.isEmpty ?? String.isEmpty,
|
|
23
22
|
});
|
|
@@ -49,7 +48,9 @@ export const validateAll = (rules) => (value) => {
|
|
|
49
48
|
onSome: message => Invalid({ value, errors: [resolveMessage(message, value)] }),
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
|
-
return pipe(rules.rules, Array.filterMap(([predicate, message]) =>
|
|
51
|
+
return pipe(rules.rules, Array.filterMap(([predicate, message]) => !predicate(value)
|
|
52
|
+
? Result.succeed(resolveMessage(message, value))
|
|
53
|
+
: Result.failVoid), Array.match({
|
|
53
54
|
onEmpty: () => Valid({ value }),
|
|
54
55
|
onNonEmpty: errors => Invalid({ value, errors }),
|
|
55
56
|
}));
|
|
@@ -90,12 +91,12 @@ export const anyInvalid = (states) => Array.some(states, isInvalid);
|
|
|
90
91
|
// STRING RULES
|
|
91
92
|
/** Creates a `Rule` that checks if a string meets a minimum length. */
|
|
92
93
|
export const minLength = (min, message) => [
|
|
93
|
-
flow(String.length, Number_.
|
|
94
|
+
flow(String.length, Number_.isGreaterThanOrEqualTo(min)),
|
|
94
95
|
message ?? `Must be at least ${min} characters`,
|
|
95
96
|
];
|
|
96
97
|
/** Creates a `Rule` that checks if a string does not exceed a maximum length. */
|
|
97
98
|
export const maxLength = (max, message) => [
|
|
98
|
-
flow(String.length, Number_.
|
|
99
|
+
flow(String.length, Number_.isLessThanOrEqualTo(max)),
|
|
99
100
|
message ?? `Must be at most ${max} characters`,
|
|
100
101
|
];
|
|
101
102
|
/** Creates a `Rule` that checks if a string matches a regular expression. */
|
package/dist/file/error.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const FileReadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").
|
|
1
|
+
declare const FileReadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
2
2
|
readonly _tag: "FileReadError";
|
|
3
3
|
} & Readonly<A>;
|
|
4
4
|
/** Error raised when a `FileReader` operation fails. */
|
package/dist/file/file.d.ts
CHANGED
package/dist/file/file.js
CHANGED
package/dist/file/reader.d.ts
CHANGED
|
@@ -6,14 +6,14 @@ import type { File } from './file.js';
|
|
|
6
6
|
*
|
|
7
7
|
* Fails with a `FileReadError` if the browser's `FileReader` encounters an
|
|
8
8
|
* error (e.g. the file was deleted while reading). Handle failures with
|
|
9
|
-
* `Effect.
|
|
9
|
+
* `Effect.catch` to convert them into a failure Message.
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
13
13
|
* ReadResumeText(
|
|
14
14
|
* File.readAsText(file).pipe(
|
|
15
15
|
* Effect.map(text => GotResumeText({ text })),
|
|
16
|
-
* Effect.
|
|
16
|
+
* Effect.catch(error => Effect.succeed(FailedReadResume({ error: error.reason }))),
|
|
17
17
|
* ),
|
|
18
18
|
* )
|
|
19
19
|
* ```
|
|
@@ -28,7 +28,7 @@ export declare const readAsText: (file: File) => Effect.Effect<string, FileReadE
|
|
|
28
28
|
* ReadImagePreview(
|
|
29
29
|
* File.readAsDataUrl(imageFile).pipe(
|
|
30
30
|
* Effect.map(dataUrl => GotImagePreview({ dataUrl })),
|
|
31
|
-
* Effect.
|
|
31
|
+
* Effect.catch(error => Effect.succeed(FailedReadImage({ error: error.reason }))),
|
|
32
32
|
* ),
|
|
33
33
|
* )
|
|
34
34
|
* ```
|
|
@@ -47,7 +47,7 @@ export declare const readAsDataUrl: (file: File) => Effect.Effect<string, FileRe
|
|
|
47
47
|
* File.readAsArrayBuffer(file).pipe(
|
|
48
48
|
* Effect.flatMap(buffer => uploadToServer(buffer)),
|
|
49
49
|
* Effect.map(() => SucceededUpload()),
|
|
50
|
-
* Effect.
|
|
50
|
+
* Effect.catch(error => Effect.succeed(FailedUpload({ reason: String(error) }))),
|
|
51
51
|
* ),
|
|
52
52
|
* )
|
|
53
53
|
* ```
|
package/dist/file/reader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
2
|
import { FileReadError } from './error.js';
|
|
3
|
-
const readFile = (file, mode, extract) => Effect.
|
|
3
|
+
const readFile = (file, mode, extract) => Effect.callback((resume, signal) => {
|
|
4
4
|
const reader = new FileReader();
|
|
5
5
|
const handleLoad = () => {
|
|
6
6
|
const extracted = extract(reader);
|
|
@@ -43,14 +43,14 @@ const readFile = (file, mode, extract) => Effect.async((resume, signal) => {
|
|
|
43
43
|
*
|
|
44
44
|
* Fails with a `FileReadError` if the browser's `FileReader` encounters an
|
|
45
45
|
* error (e.g. the file was deleted while reading). Handle failures with
|
|
46
|
-
* `Effect.
|
|
46
|
+
* `Effect.catch` to convert them into a failure Message.
|
|
47
47
|
*
|
|
48
48
|
* @example
|
|
49
49
|
* ```typescript
|
|
50
50
|
* ReadResumeText(
|
|
51
51
|
* File.readAsText(file).pipe(
|
|
52
52
|
* Effect.map(text => GotResumeText({ text })),
|
|
53
|
-
* Effect.
|
|
53
|
+
* Effect.catch(error => Effect.succeed(FailedReadResume({ error: error.reason }))),
|
|
54
54
|
* ),
|
|
55
55
|
* )
|
|
56
56
|
* ```
|
|
@@ -65,7 +65,7 @@ export const readAsText = (file) => readFile(file, 'text', reader => typeof read
|
|
|
65
65
|
* ReadImagePreview(
|
|
66
66
|
* File.readAsDataUrl(imageFile).pipe(
|
|
67
67
|
* Effect.map(dataUrl => GotImagePreview({ dataUrl })),
|
|
68
|
-
* Effect.
|
|
68
|
+
* Effect.catch(error => Effect.succeed(FailedReadImage({ error: error.reason }))),
|
|
69
69
|
* ),
|
|
70
70
|
* )
|
|
71
71
|
* ```
|
|
@@ -84,7 +84,7 @@ export const readAsDataUrl = (file) => readFile(file, 'dataUrl', reader => typeo
|
|
|
84
84
|
* File.readAsArrayBuffer(file).pipe(
|
|
85
85
|
* Effect.flatMap(buffer => uploadToServer(buffer)),
|
|
86
86
|
* Effect.map(() => SucceededUpload()),
|
|
87
|
-
* Effect.
|
|
87
|
+
* Effect.catch(error => Effect.succeed(FailedUpload({ reason: String(error) }))),
|
|
88
88
|
* ),
|
|
89
89
|
* )
|
|
90
90
|
* ```
|
package/dist/file/select.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Array, Effect } from 'effect';
|
|
2
|
-
const openPicker = ({ accept, multiple, }) => Effect.
|
|
2
|
+
const openPicker = ({ accept, multiple, }) => Effect.callback((resume, signal) => {
|
|
3
3
|
const input = document.createElement('input');
|
|
4
4
|
input.type = 'file';
|
|
5
5
|
input.accept = accept.join(',');
|