@sjcx/vorma 0.0.0-pre.2 → 0.0.0-pre.3
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/build/assemble-artifacts.d.ts +1 -1
- package/dist/build/bundle-client.d.ts +1 -1
- package/dist/build/cli.js +27 -37
- package/dist/build/compile-application.d.ts +2 -2
- package/dist/build/development-artifacts.d.ts +1 -1
- package/dist/build/development-build.d.ts +3 -6
- package/dist/build/development-work.d.ts +2 -3
- package/dist/build/generate-application.d.ts +2 -2
- package/dist/build/index.d.ts +2 -3
- package/dist/build/index.js +1 -1
- package/dist/build/inspect-projects.d.ts +3 -3
- package/dist/build/load-config.d.ts +0 -2
- package/dist/build/publish-artifacts.d.ts +1 -4
- package/dist/build/render-client-transport.d.ts +1 -1
- package/dist/build/render-server-generated.d.ts +1 -12
- package/dist/build/render-types.d.ts +1 -1
- package/dist/build/resolve-config.d.ts +2 -4
- package/dist/build/source-layout.d.ts +1 -1
- package/dist/{build-DcP5_DUV.js → build-sHSh5zaX.js} +67 -282
- package/package.json +5 -36
- package/dist/build/compile-server.d.ts +0 -42
- package/dist/client/assembly.d.ts +0 -40
- package/dist/client/browser-http-client.d.ts +0 -10
- package/dist/client/client-loaders.d.ts +0 -93
- package/dist/client/commit.d.ts +0 -41
- package/dist/client/contracts.d.ts +0 -192
- package/dist/client/core.d.ts +0 -45
- package/dist/client/development.d.ts +0 -16
- package/dist/client/document-recovery.d.ts +0 -4
- package/dist/client/endpoints.d.ts +0 -54
- package/dist/client/errors.d.ts +0 -87
- package/dist/client/freshness.d.ts +0 -51
- package/dist/client/head.d.ts +0 -14
- package/dist/client/history.d.ts +0 -25
- package/dist/client/index.d.ts +0 -80
- package/dist/client/index.js +0 -150
- package/dist/client/links.d.ts +0 -48
- package/dist/client/materialize.d.ts +0 -21
- package/dist/client/modules.d.ts +0 -2
- package/dist/client/navigation.d.ts +0 -47
- package/dist/client/payload.d.ts +0 -54
- package/dist/client/prefetch.d.ts +0 -28
- package/dist/client/prepare.d.ts +0 -47
- package/dist/client/projections.d.ts +0 -26
- package/dist/client/queries.d.ts +0 -33
- package/dist/client/react/application.d.ts +0 -87
- package/dist/client/react/hooks.d.ts +0 -36
- package/dist/client/react/index.d.ts +0 -5
- package/dist/client/react/index.js +0 -3237
- package/dist/client/react/link.d.ts +0 -27
- package/dist/client/react/view.d.ts +0 -86
- package/dist/client/request.d.ts +0 -16
- package/dist/client/route-context.d.ts +0 -31
- package/dist/client/route-matching.d.ts +0 -22
- package/dist/client/route-synchronization.d.ts +0 -30
- package/dist/client/route-url.d.ts +0 -5
- package/dist/client/runtime.d.ts +0 -82
- package/dist/client/scroll.d.ts +0 -16
- package/dist/client/services.d.ts +0 -34
- package/dist/client/state.d.ts +0 -102
- package/dist/client/static-assets.d.ts +0 -3
- package/dist/client/stylesheets.d.ts +0 -7
- package/dist/client/transport-type-entries.d.ts +0 -2
- package/dist/client/types.d.ts +0 -152
- package/dist/client/view-definition.d.ts +0 -24
- package/dist/client/work-indicator.d.ts +0 -18
- package/dist/compile-Me8EOyMK.js +0 -870
- package/dist/development-B_rxuwY7.js +0 -128
- package/dist/hash-set-BPx3iXec.js +0 -141
- package/dist/href-Cqyax8Y0.js +0 -357
- package/dist/materialize-DZ7VSLFk.js +0 -739
- package/dist/metadata-BoPKo-G2.js +0 -32
- package/dist/primitives/tasks/index.d.ts +0 -1
- package/dist/primitives/tasks/index.js +0 -1
- package/dist/route-context-CtY_9U_W.js +0 -559
- package/dist/route-matching-D_uSG2P9.js +0 -33
- package/dist/search-parse-0f7oqVsG.js +0 -375
- package/dist/server/config/index.d.ts +0 -36
- package/dist/server/config/index.js +0 -30
- package/dist/server/development/metadata.d.ts +0 -11
- package/dist/server/document.d.ts +0 -37
- package/dist/server/form-data.d.ts +0 -21
- package/dist/server/graph/compile.d.ts +0 -118
- package/dist/server/graph/declarations.d.ts +0 -117
- package/dist/server/graph/literal-error-tag.d.ts +0 -14
- package/dist/server/graph/pattern-conflicts.d.ts +0 -36
- package/dist/server/graph/search-schema.d.ts +0 -13
- package/dist/server/graph/transport-schema.d.ts +0 -11
- package/dist/server/index.d.ts +0 -310
- package/dist/server/index.js +0 -2311
- package/dist/server/public-assets.d.ts +0 -18
- package/dist/server/runtime/application.d.ts +0 -15
- package/dist/server/runtime/assets.d.ts +0 -15
- package/dist/server/runtime/context.d.ts +0 -96
- package/dist/server/runtime/domain-errors.d.ts +0 -11
- package/dist/server/runtime/effects.d.ts +0 -83
- package/dist/server/runtime/execute.d.ts +0 -13
- package/dist/server/runtime/finalize.d.ts +0 -44
- package/dist/server/runtime/handler.d.ts +0 -106
- package/dist/server/runtime/head.d.ts +0 -22
- package/dist/server/runtime/payload.d.ts +0 -50
- package/dist/server/runtime/pipeline.d.ts +0 -27
- package/dist/server/runtime/plan.d.ts +0 -98
- package/dist/server/runtime/render-document.d.ts +0 -16
- package/dist/server/runtime/startup-error.d.ts +0 -11
- package/dist/server/runtime/transport-type-entries.d.ts +0 -2
- package/dist/server/runtime/vercel-deployment.d.ts +0 -2
- package/dist/server/url-pathname.d.ts +0 -13
- package/dist/static-assets-BrH3O0M8.js +0 -199
- package/dist/universal/generated-types.d.ts +0 -9
- package/dist/universal/href.d.ts +0 -17
- package/dist/universal/http-method.d.ts +0 -4
- package/dist/universal/json-transport.d.ts +0 -14
- package/dist/universal/null-prototype-record.d.ts +0 -7
- package/dist/universal/path-wire.d.ts +0 -71
- package/dist/universal/pattern-language.d.ts +0 -4
- package/dist/universal/protocol-schemas.d.ts +0 -99
- package/dist/universal/protocol.d.ts +0 -162
- package/dist/universal/search-grammar.d.ts +0 -7
- package/dist/universal/search-parse.d.ts +0 -22
- package/dist/universal/search-serialize.d.ts +0 -16
- package/dist/universal/search-shape.d.ts +0 -32
- package/dist/universal/static-assets.d.ts +0 -2
- package/dist/universal/transport-types/big-decimal.d.ts +0 -13
- package/dist/universal/transport-types/chunk.d.ts +0 -8
- package/dist/universal/transport-types/date-time-utc.d.ts +0 -13
- package/dist/universal/transport-types/date-time-zoned.d.ts +0 -13
- package/dist/universal/transport-types/duration.d.ts +0 -13
- package/dist/universal/transport-types/hash-map.d.ts +0 -8
- package/dist/universal/transport-types/hash-set.d.ts +0 -8
- package/dist/universal/transport-types/option.d.ts +0 -10
- package/dist/universal/transport-types/redacted.d.ts +0 -9
- package/dist/universal/value-transport.d.ts +0 -117
- package/dist/value-transport-Bst4Hk-n.js +0 -864
- /package/dist/{universal → build}/content-digest.d.ts +0 -0
|
@@ -1,864 +0,0 @@
|
|
|
1
|
-
import { Result } from "effect";
|
|
2
|
-
import { compileFlatPattern, compileNestedPattern } from "@vorma/primitives/matcher";
|
|
3
|
-
//#region src/universal/protocol.ts
|
|
4
|
-
/** Process-environment names consumed as part of a deployment integration. */
|
|
5
|
-
const PROCESS_ENVIRONMENT_PROTOCOL = {
|
|
6
|
-
vercelSkewProtectionEnabledVariable: "VERCEL_SKEW_PROTECTION_ENABLED",
|
|
7
|
-
vercelDeploymentIdVariable: "VERCEL_DEPLOYMENT_ID"
|
|
8
|
-
};
|
|
9
|
-
/** Private development coordination between the launcher and mounted runtime. */
|
|
10
|
-
const DEVELOPMENT_PROTOCOL = {
|
|
11
|
-
serverPortEnvironmentVariable: "PORT",
|
|
12
|
-
readinessPath: "/.vorma/healthz"
|
|
13
|
-
};
|
|
14
|
-
/** Request and response vocabulary shared by the browser and runtime server. */
|
|
15
|
-
const HTTP_PROTOCOL = {
|
|
16
|
-
queryKeys: {
|
|
17
|
-
viewPayload: "vorma-json",
|
|
18
|
-
deployment: "dpl",
|
|
19
|
-
streamResume: "vorma_resume"
|
|
20
|
-
},
|
|
21
|
-
requestHeaders: {
|
|
22
|
-
clientBuildId: "x-vorma-client-build-id",
|
|
23
|
-
clientAcceptsRedirect: "x-accepts-client-redirect",
|
|
24
|
-
vercelDeploymentId: "x-deployment-id"
|
|
25
|
-
},
|
|
26
|
-
responseHeaders: {
|
|
27
|
-
clientBuildId: "x-vorma-client-build-id",
|
|
28
|
-
buildSkew: "x-vorma-build-skew",
|
|
29
|
-
clientRedirect: "x-client-redirect",
|
|
30
|
-
clientRedirectStatus: "x-client-redirect-status"
|
|
31
|
-
},
|
|
32
|
-
buildSkewBody: "{\"ok\":true}"
|
|
33
|
-
};
|
|
34
|
-
/** Reserved markup names shared by server rendering and browser reconciliation. */
|
|
35
|
-
const DOCUMENT_PROTOCOL = {
|
|
36
|
-
elementIds: {
|
|
37
|
-
root: "vorma-root",
|
|
38
|
-
data: "vorma-data-json",
|
|
39
|
-
criticalCss: "vorma-critical-css"
|
|
40
|
-
},
|
|
41
|
-
attributes: {
|
|
42
|
-
cssBundle: "data-vorma-css-bundle",
|
|
43
|
-
cssPreload: "data-vorma-css-preload",
|
|
44
|
-
staticAsset: "data-vorma-static-asset",
|
|
45
|
-
linkActiveExact: "data-vorma-active-exact",
|
|
46
|
-
linkActiveAncestor: "data-vorma-active-ancestor",
|
|
47
|
-
linkPendingExact: "data-vorma-pending-exact",
|
|
48
|
-
linkPendingAncestor: "data-vorma-pending-ancestor"
|
|
49
|
-
},
|
|
50
|
-
headComments: {
|
|
51
|
-
title: "vorma-head:title",
|
|
52
|
-
meta: "vorma-head:meta",
|
|
53
|
-
rest: "vorma-head:rest",
|
|
54
|
-
assets: "vorma-head:assets"
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
/** Persistent names owned by the browser client. */
|
|
58
|
-
const BROWSER_STATE_PROTOCOL = {
|
|
59
|
-
historyStateFields: {
|
|
60
|
-
userState: "vorma-user-state",
|
|
61
|
-
entryKey: "vorma-entry-key"
|
|
62
|
-
},
|
|
63
|
-
/** Session storage key holding saved scroll positions by history entry key. */
|
|
64
|
-
scrollStorageKey: "vorma-scroll",
|
|
65
|
-
apiIdentityArrayPrefix: "vorma-api"
|
|
66
|
-
};
|
|
67
|
-
/** URL-search escaping and marker vocabulary shared by both runtimes. */
|
|
68
|
-
const SEARCH_PARAMETER_PROTOCOL = {
|
|
69
|
-
escapePrefix: "~",
|
|
70
|
-
keySeparator: ".",
|
|
71
|
-
keySegmentEscapes: {
|
|
72
|
-
tilde: "~0",
|
|
73
|
-
separator: "~1",
|
|
74
|
-
empty: "~2"
|
|
75
|
-
},
|
|
76
|
-
valueMarkers: {
|
|
77
|
-
null: "~n",
|
|
78
|
-
emptyArray: "~a",
|
|
79
|
-
emptyObject: "~o",
|
|
80
|
-
escapedScalarPrefix: "~s"
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
const PUBLIC_OUTPUT_FILE_NAME_PREFIX = "vorma_out_";
|
|
84
|
-
/** Vorma-owned output layout and stable generated names. */
|
|
85
|
-
const ARTIFACT_PROTOCOL = {
|
|
86
|
-
/**
|
|
87
|
-
* The directory Vorma owns beside each configured entry. The name is fixed; applications do not configure it.
|
|
88
|
-
*/
|
|
89
|
-
vormaDirectoryName: "_vorma",
|
|
90
|
-
/** Inside the client entry’s `_vorma`: published public assets. */
|
|
91
|
-
publicDirectoryName: "public",
|
|
92
|
-
/** Inside each entry’s `_vorma`: the ignore file covering its output. */
|
|
93
|
-
ignoreFileName: ".gitignore",
|
|
94
|
-
ignoreFileSource: "*\n",
|
|
95
|
-
/** Inside the server entry's `_vorma`: the registered declarations. */
|
|
96
|
-
generatedBuildFileName: "build.gen.ts",
|
|
97
|
-
compiledServerEntryFileName: "entry.mjs",
|
|
98
|
-
compiledRuntimeFileName: "runtime.gen.mjs",
|
|
99
|
-
productionMetadataFileName: "metadata.gen.json",
|
|
100
|
-
compiledServerModuleExtension: ".mjs",
|
|
101
|
-
/** Inside the client entry's `_vorma`. */
|
|
102
|
-
generatedAssetKeysFileName: "assets.gen.d.ts",
|
|
103
|
-
/** Inside the client entry's `_vorma`: runtime adapters for contract Effect types. */
|
|
104
|
-
generatedClientTransportFileName: "transport.gen.ts",
|
|
105
|
-
/** In both boundaries: the declaration augmenting that boundary's Vorma entry. */
|
|
106
|
-
generatedClientContractsFileName: "client.gen.d.ts",
|
|
107
|
-
generatedServerContractsFileName: "server.gen.d.ts",
|
|
108
|
-
publicOutputFileNamePrefix: PUBLIC_OUTPUT_FILE_NAME_PREFIX,
|
|
109
|
-
publicModuleFileNamePattern: `${PUBLIC_OUTPUT_FILE_NAME_PREFIX}[name]-[hash].js`,
|
|
110
|
-
publicAssetFileNamePattern: `${PUBLIC_OUTPUT_FILE_NAME_PREFIX}[name]-[hash][extname]`
|
|
111
|
-
};
|
|
112
|
-
/** Identifiers shared across package entries, discovery, and generated code. */
|
|
113
|
-
const FRAMEWORK_IDENTITY_PROTOCOL = {
|
|
114
|
-
brands: {},
|
|
115
|
-
moduleSpecifiers: {
|
|
116
|
-
build: "vorma/build",
|
|
117
|
-
server: "vorma/server",
|
|
118
|
-
client: "vorma/client",
|
|
119
|
-
clientReact: "vorma/client/react",
|
|
120
|
-
clientTransportTypes: "virtual:vorma/client-transport-types"
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
/**
|
|
124
|
-
* Tags the framework itself reports in command error channels. A declared
|
|
125
|
-
* domain tag must not collide with one: `Effect.catchTag` could not tell
|
|
126
|
-
* them apart. Declaration compilation rejects collisions.
|
|
127
|
-
*/
|
|
128
|
-
const FRAMEWORK_ERROR_TAGS = [
|
|
129
|
-
"InputError",
|
|
130
|
-
"BuildMismatchError",
|
|
131
|
-
"TransportError",
|
|
132
|
-
"HandlerError",
|
|
133
|
-
"QueryRedirected",
|
|
134
|
-
"StreamResumeUnavailable",
|
|
135
|
-
"NavigationError",
|
|
136
|
-
"RevalidationError",
|
|
137
|
-
"PrefetchError"
|
|
138
|
-
];
|
|
139
|
-
//#endregion
|
|
140
|
-
//#region src/universal/null-prototype-record.ts
|
|
141
|
-
/**
|
|
142
|
-
* A record with no prototype: a key spelled `__proto__` or `constructor` is
|
|
143
|
-
* an own property and nothing else, so a name from the wire can index it
|
|
144
|
-
* without reaching inherited members. `Object.create` is typed as `any`;
|
|
145
|
-
* this function is the one place that typing meets the record's type.
|
|
146
|
-
*/
|
|
147
|
-
function makeNullPrototypeRecord() {
|
|
148
|
-
return Object.create(null);
|
|
149
|
-
}
|
|
150
|
-
//#endregion
|
|
151
|
-
//#region src/universal/pattern-language.ts
|
|
152
|
-
/** The pattern language: dynamic segments start with a colon, a lone star is a splat, `_index` names a layout's index. */
|
|
153
|
-
const FLAT_PATTERN_LANGUAGE = {
|
|
154
|
-
kind: "flat",
|
|
155
|
-
dynamicParamPrefix: ":",
|
|
156
|
-
splatSegment: "*"
|
|
157
|
-
};
|
|
158
|
-
const NESTED_PATTERN_LANGUAGE = {
|
|
159
|
-
kind: "nested",
|
|
160
|
-
dynamicParamPrefix: ":",
|
|
161
|
-
explicitIndexSegment: "_index",
|
|
162
|
-
splatSegment: "*"
|
|
163
|
-
};
|
|
164
|
-
//#endregion
|
|
165
|
-
//#region src/universal/path-wire.ts
|
|
166
|
-
/** Converts an absolute request pathname to the canonical spelling used for matching. */
|
|
167
|
-
function canonicalizeRequestPathForMatcher(path) {
|
|
168
|
-
if (!path.startsWith("/")) return Result.fail({
|
|
169
|
-
_tag: "PathMustBeAbsolute",
|
|
170
|
-
path
|
|
171
|
-
});
|
|
172
|
-
const wellFormed = checkWellFormedUnicode(path);
|
|
173
|
-
if (Result.isFailure(wellFormed)) return Result.fail(wellFormed.failure);
|
|
174
|
-
const encoded = [];
|
|
175
|
-
for (const segment of path.split("/")) {
|
|
176
|
-
if (segment === "") {
|
|
177
|
-
encoded.push("");
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
const decoded = decodePercentSegment(segment);
|
|
181
|
-
if (Result.isFailure(decoded)) return Result.fail(decoded.failure);
|
|
182
|
-
encoded.push(encodeWireText(decoded.success));
|
|
183
|
-
}
|
|
184
|
-
return Result.succeed(encoded.join("/"));
|
|
185
|
-
}
|
|
186
|
-
/** Encodes a logical authored route pattern without interpreting static percent escapes. */
|
|
187
|
-
function encodeRoutePatternForMatcher(pattern) {
|
|
188
|
-
if (!pattern.startsWith("/")) return Result.fail({
|
|
189
|
-
_tag: "PathMustBeAbsolute",
|
|
190
|
-
path: pattern
|
|
191
|
-
});
|
|
192
|
-
const wellFormed = checkWellFormedUnicode(pattern);
|
|
193
|
-
if (Result.isFailure(wellFormed)) return Result.fail(wellFormed.failure);
|
|
194
|
-
const encoded = [];
|
|
195
|
-
for (const segment of pattern.split("/")) {
|
|
196
|
-
if (segment === "" || segment === "*" || segment.startsWith(":")) {
|
|
197
|
-
encoded.push(segment);
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
if (segment === "." || segment === "..") return Result.fail({
|
|
201
|
-
_tag: "StaticDotPathSegment",
|
|
202
|
-
pattern,
|
|
203
|
-
segment
|
|
204
|
-
});
|
|
205
|
-
encoded.push(encodeWireText(segment));
|
|
206
|
-
}
|
|
207
|
-
return Result.succeed(encoded.join("/"));
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Compiles an authored UI route pattern: wire encoding first, then the
|
|
211
|
-
* nested pattern language. Every UI pattern enters the matcher through this
|
|
212
|
-
* function, in the graph, the build, and the plan.
|
|
213
|
-
*/
|
|
214
|
-
function compileUiPattern(pattern) {
|
|
215
|
-
const encoded = encodeRoutePatternForMatcher(pattern);
|
|
216
|
-
if (Result.isFailure(encoded)) return Result.fail(encoded.failure);
|
|
217
|
-
return compileNestedPattern({
|
|
218
|
-
pattern: encoded.success,
|
|
219
|
-
language: NESTED_PATTERN_LANGUAGE
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
/** Compiles an authored endpoint or middleware pattern in the flat pattern language. */
|
|
223
|
-
function compileEndpointPattern(pattern) {
|
|
224
|
-
const encoded = encodeRoutePatternForMatcher(pattern);
|
|
225
|
-
if (Result.isFailure(encoded)) return Result.fail(encoded.failure);
|
|
226
|
-
return compileFlatPattern({
|
|
227
|
-
pattern: encoded.success,
|
|
228
|
-
language: FLAT_PATTERN_LANGUAGE
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
/** Decodes a match's wire captures to the logical values supplied to application code. */
|
|
232
|
-
function decodeMatchCaptures(match) {
|
|
233
|
-
const params = makeNullPrototypeRecord();
|
|
234
|
-
for (const [name, value] of Object.entries(match.dynamicParams)) {
|
|
235
|
-
const decoded = decodePathCapture(value);
|
|
236
|
-
if (Result.isFailure(decoded)) return Result.fail(decoded.failure);
|
|
237
|
-
params[name] = decoded.success;
|
|
238
|
-
}
|
|
239
|
-
const splatValues = [];
|
|
240
|
-
for (const value of match.splatValues) {
|
|
241
|
-
const decoded = decodePathCapture(value);
|
|
242
|
-
if (Result.isFailure(decoded)) return Result.fail(decoded.failure);
|
|
243
|
-
splatValues.push(decoded.success);
|
|
244
|
-
}
|
|
245
|
-
return Result.succeed({
|
|
246
|
-
params,
|
|
247
|
-
splatValues
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
/** Encodes one non-empty logical dynamic or splat value as one wire segment. */
|
|
251
|
-
function encodePathCapture(value) {
|
|
252
|
-
if (value === "") return Result.fail({ _tag: "EmptyPathCapture" });
|
|
253
|
-
if (value === "." || value === "..") return Result.fail({
|
|
254
|
-
_tag: "DotPathCapture",
|
|
255
|
-
value
|
|
256
|
-
});
|
|
257
|
-
const wellFormed = checkWellFormedUnicode(value);
|
|
258
|
-
if (Result.isFailure(wellFormed)) return Result.fail(wellFormed.failure);
|
|
259
|
-
return Result.succeed(encodeWireText(value));
|
|
260
|
-
}
|
|
261
|
-
/** Decodes one matched wire segment to the logical value supplied to application code. */
|
|
262
|
-
function decodePathCapture(segment) {
|
|
263
|
-
if (segment === "") return Result.fail({ _tag: "EmptyPathCapture" });
|
|
264
|
-
if (segment.includes("/")) return Result.fail({
|
|
265
|
-
_tag: "PathCaptureContainsSeparator",
|
|
266
|
-
segment
|
|
267
|
-
});
|
|
268
|
-
return Result.flatMap(decodePercentSegment(segment), (value) => {
|
|
269
|
-
return value === "." || value === ".." ? Result.fail({
|
|
270
|
-
_tag: "DotPathCapture",
|
|
271
|
-
value
|
|
272
|
-
}) : Result.succeed(value);
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
function formatPathWireError(error) {
|
|
276
|
-
switch (error._tag) {
|
|
277
|
-
case "PathMustBeAbsolute": return `path ${JSON.stringify(error.path)} must begin with /`;
|
|
278
|
-
case "MalformedPercentEncoding": return `malformed percent encoding at offset ${error.offset} of path segment ${JSON.stringify(error.segment)}`;
|
|
279
|
-
case "InvalidPercentEncodedUtf8": return `percent-decoded path segment is not UTF-8: ${JSON.stringify(error.segment)}`;
|
|
280
|
-
case "MalformedUnicode": return `value contains an unpaired Unicode surrogate at offset ${error.offset}`;
|
|
281
|
-
case "EmptyPathCapture": return "path capture cannot be empty";
|
|
282
|
-
case "DotPathCapture": return `path parameter ${JSON.stringify(error.value)} cannot be a literal URL segment because URL normalization would erase it`;
|
|
283
|
-
case "PathCaptureContainsSeparator": return "one path wire segment cannot contain a literal / separator";
|
|
284
|
-
case "StaticDotPathSegment": return `route pattern ${JSON.stringify(error.pattern)} contains static segment ${JSON.stringify(error.segment)}, which URL normalization would erase`;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
function checkWellFormedUnicode(value) {
|
|
288
|
-
for (let offset = 0; offset < value.length; offset++) {
|
|
289
|
-
const unit = value.charCodeAt(offset);
|
|
290
|
-
if (unit >= 55296 && unit <= 56319) {
|
|
291
|
-
const next = value.charCodeAt(offset + 1);
|
|
292
|
-
if (!(next >= 56320 && next <= 57343)) return Result.fail({
|
|
293
|
-
_tag: "MalformedUnicode",
|
|
294
|
-
value,
|
|
295
|
-
offset
|
|
296
|
-
});
|
|
297
|
-
offset += 1;
|
|
298
|
-
} else if (unit >= 56320 && unit <= 57343) return Result.fail({
|
|
299
|
-
_tag: "MalformedUnicode",
|
|
300
|
-
value,
|
|
301
|
-
offset
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
return Result.succeed(void 0);
|
|
305
|
-
}
|
|
306
|
-
function decodePercentSegment(segment) {
|
|
307
|
-
const wellFormed = checkWellFormedUnicode(segment);
|
|
308
|
-
if (Result.isFailure(wellFormed)) return Result.fail(wellFormed.failure);
|
|
309
|
-
for (let offset = 0; offset < segment.length; offset++) if (segment[offset] === "%") {
|
|
310
|
-
const high = toHexValue(segment.charCodeAt(offset + 1));
|
|
311
|
-
const low = toHexValue(segment.charCodeAt(offset + 2));
|
|
312
|
-
if (high === null || low === null) return Result.fail({
|
|
313
|
-
_tag: "MalformedPercentEncoding",
|
|
314
|
-
segment,
|
|
315
|
-
offset
|
|
316
|
-
});
|
|
317
|
-
offset += 2;
|
|
318
|
-
}
|
|
319
|
-
return Result.try({
|
|
320
|
-
try: () => decodeURIComponent(segment),
|
|
321
|
-
catch: () => {
|
|
322
|
-
return {
|
|
323
|
-
_tag: "InvalidPercentEncodedUtf8",
|
|
324
|
-
segment
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
function encodeWireText(value) {
|
|
330
|
-
return encodeURIComponent(value).replaceAll("%2B", "+").replace(/[!'()*]/g, (character) => {
|
|
331
|
-
return `%${character.charCodeAt(0).toString(16).toUpperCase()}`;
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
function toHexValue(unit) {
|
|
335
|
-
if (unit >= 48 && unit <= 57) return unit - 48;
|
|
336
|
-
if (unit >= 65 && unit <= 70) return unit - 65 + 10;
|
|
337
|
-
if (unit >= 97 && unit <= 102) return unit - 97 + 10;
|
|
338
|
-
return null;
|
|
339
|
-
}
|
|
340
|
-
//#endregion
|
|
341
|
-
//#region src/universal/value-transport.ts
|
|
342
|
-
const TRANSPORT_MARK_KINDS = /* @__PURE__ */ new Set([
|
|
343
|
-
"date",
|
|
344
|
-
"bigint",
|
|
345
|
-
"number",
|
|
346
|
-
"undefined",
|
|
347
|
-
"map",
|
|
348
|
-
"set",
|
|
349
|
-
"url",
|
|
350
|
-
"url-search-params",
|
|
351
|
-
"regexp",
|
|
352
|
-
"option",
|
|
353
|
-
"redacted",
|
|
354
|
-
"chunk",
|
|
355
|
-
"duration",
|
|
356
|
-
"big-decimal",
|
|
357
|
-
"date-time-utc",
|
|
358
|
-
"date-time-zoned",
|
|
359
|
-
"hash-map",
|
|
360
|
-
"hash-set"
|
|
361
|
-
]);
|
|
362
|
-
const EFFECT_TRANSPORT_TYPES = [
|
|
363
|
-
{
|
|
364
|
-
name: "option",
|
|
365
|
-
representationId: "effect/schema/Option"
|
|
366
|
-
},
|
|
367
|
-
{
|
|
368
|
-
name: "redacted",
|
|
369
|
-
representationId: "effect/schema/Redacted"
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
name: "chunk",
|
|
373
|
-
representationId: "effect/schema/Chunk"
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
name: "duration",
|
|
377
|
-
representationId: "effect/schema/Duration"
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
name: "big-decimal",
|
|
381
|
-
representationId: "effect/schema/BigDecimal"
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
name: "date-time-utc",
|
|
385
|
-
representationId: "effect/schema/DateTimeUtc"
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
name: "date-time-zoned",
|
|
389
|
-
representationId: "effect/schema/DateTimeZoned"
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
name: "hash-map",
|
|
393
|
-
representationId: "effect/schema/HashMap"
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
name: "hash-set",
|
|
397
|
-
representationId: "effect/schema/HashSet"
|
|
398
|
-
}
|
|
399
|
-
];
|
|
400
|
-
function encodeTransportedValue(input) {
|
|
401
|
-
const marks = [];
|
|
402
|
-
const active = /* @__PURE__ */ new Set();
|
|
403
|
-
const json = encodeValue({
|
|
404
|
-
value: input.value,
|
|
405
|
-
path: [],
|
|
406
|
-
marks,
|
|
407
|
-
active,
|
|
408
|
-
typeEntries: input.typeEntries
|
|
409
|
-
});
|
|
410
|
-
return Result.map(json, (encoded) => {
|
|
411
|
-
return {
|
|
412
|
-
json: encoded,
|
|
413
|
-
marks
|
|
414
|
-
};
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
/** The reader's JSON came from a parser, so its type is only `unknown` here; the marks are what the reader checks. */
|
|
418
|
-
function decodeTransportedValue(input) {
|
|
419
|
-
const marks = [...input.transported.marks].sort((left, right) => right.path.length - left.path.length);
|
|
420
|
-
const paths = /* @__PURE__ */ new Set();
|
|
421
|
-
for (const mark of marks) {
|
|
422
|
-
const path = JSON.stringify(mark.path);
|
|
423
|
-
if (paths.has(path)) return Result.fail({
|
|
424
|
-
_tag: "InvalidTransportMark",
|
|
425
|
-
path: mark.path,
|
|
426
|
-
reason: "a value can have only one transport mark"
|
|
427
|
-
});
|
|
428
|
-
paths.add(path);
|
|
429
|
-
}
|
|
430
|
-
const root = { value: input.transported.json };
|
|
431
|
-
for (const mark of marks) {
|
|
432
|
-
const restored = restoreAt({
|
|
433
|
-
root,
|
|
434
|
-
mark,
|
|
435
|
-
typeEntries: input.typeEntries
|
|
436
|
-
});
|
|
437
|
-
if (Result.isFailure(restored)) return restored;
|
|
438
|
-
}
|
|
439
|
-
return Result.succeed(root.value);
|
|
440
|
-
}
|
|
441
|
-
function encodeValue(input) {
|
|
442
|
-
const { value, path, marks, active, typeEntries } = input;
|
|
443
|
-
if (value === null || typeof value === "boolean" || typeof value === "string") return Result.succeed(value);
|
|
444
|
-
if (typeof value === "number") {
|
|
445
|
-
if (Number.isFinite(value) && !Object.is(value, -0)) return Result.succeed(value);
|
|
446
|
-
marks.push({
|
|
447
|
-
path: [...path],
|
|
448
|
-
kind: "number"
|
|
449
|
-
});
|
|
450
|
-
return Result.succeed(Object.is(value, -0) ? "-0" : String(value));
|
|
451
|
-
}
|
|
452
|
-
if (typeof value === "undefined") {
|
|
453
|
-
marks.push({
|
|
454
|
-
path: [...path],
|
|
455
|
-
kind: "undefined"
|
|
456
|
-
});
|
|
457
|
-
return Result.succeed(null);
|
|
458
|
-
}
|
|
459
|
-
if (typeof value === "bigint") {
|
|
460
|
-
marks.push({
|
|
461
|
-
path: [...path],
|
|
462
|
-
kind: "bigint"
|
|
463
|
-
});
|
|
464
|
-
return Result.succeed(value.toString());
|
|
465
|
-
}
|
|
466
|
-
if (typeof value !== "object") return Result.fail({
|
|
467
|
-
_tag: "UntransportableValue",
|
|
468
|
-
path: [...path],
|
|
469
|
-
reason: `a ${typeof value} has no wire form`
|
|
470
|
-
});
|
|
471
|
-
if (value instanceof Date) {
|
|
472
|
-
if (Number.isNaN(value.getTime())) return Result.fail({
|
|
473
|
-
_tag: "UntransportableValue",
|
|
474
|
-
path: [...path],
|
|
475
|
-
reason: "an invalid Date has no wire form"
|
|
476
|
-
});
|
|
477
|
-
marks.push({
|
|
478
|
-
path: [...path],
|
|
479
|
-
kind: "date"
|
|
480
|
-
});
|
|
481
|
-
return Result.succeed(value.toISOString());
|
|
482
|
-
}
|
|
483
|
-
if (value instanceof URL) {
|
|
484
|
-
marks.push({
|
|
485
|
-
path: [...path],
|
|
486
|
-
kind: "url"
|
|
487
|
-
});
|
|
488
|
-
return Result.succeed(value.href);
|
|
489
|
-
}
|
|
490
|
-
if (value instanceof URLSearchParams) {
|
|
491
|
-
marks.push({
|
|
492
|
-
path: [...path],
|
|
493
|
-
kind: "url-search-params"
|
|
494
|
-
});
|
|
495
|
-
return encodeItems({
|
|
496
|
-
items: [...value.entries()].map(([key, item]) => [key, item]),
|
|
497
|
-
path,
|
|
498
|
-
marks,
|
|
499
|
-
active,
|
|
500
|
-
typeEntries
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
if (value instanceof RegExp) {
|
|
504
|
-
marks.push({
|
|
505
|
-
path: [...path],
|
|
506
|
-
kind: "regexp"
|
|
507
|
-
});
|
|
508
|
-
return Result.succeed({
|
|
509
|
-
source: value.source,
|
|
510
|
-
flags: value.flags
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
if (active.has(value)) return Result.fail({
|
|
514
|
-
_tag: "UntransportableValue",
|
|
515
|
-
path: [...path],
|
|
516
|
-
reason: "a value cannot contain itself"
|
|
517
|
-
});
|
|
518
|
-
for (const entry of typeEntries) {
|
|
519
|
-
if (!entry.matchesValue(value)) continue;
|
|
520
|
-
const projected = Result.try({
|
|
521
|
-
try: () => projectEffectTransportValue(entry, value),
|
|
522
|
-
catch: (cause) => {
|
|
523
|
-
return {
|
|
524
|
-
_tag: "UntransportableValue",
|
|
525
|
-
path: [...path],
|
|
526
|
-
reason: `${entry.kind} could not be read: ${String(cause)}`
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
if (Result.isFailure(projected)) return Result.fail(projected.failure);
|
|
531
|
-
marks.push({
|
|
532
|
-
path: [...path],
|
|
533
|
-
kind: entry.kind
|
|
534
|
-
});
|
|
535
|
-
active.add(value);
|
|
536
|
-
const encoded = encodeValue({
|
|
537
|
-
value: projected.success,
|
|
538
|
-
path,
|
|
539
|
-
marks,
|
|
540
|
-
active,
|
|
541
|
-
typeEntries
|
|
542
|
-
});
|
|
543
|
-
active.delete(value);
|
|
544
|
-
return encoded;
|
|
545
|
-
}
|
|
546
|
-
active.add(value);
|
|
547
|
-
let encoded;
|
|
548
|
-
if (value instanceof Map) {
|
|
549
|
-
marks.push({
|
|
550
|
-
path: [...path],
|
|
551
|
-
kind: "map"
|
|
552
|
-
});
|
|
553
|
-
encoded = encodeEntries({
|
|
554
|
-
entries: [...value],
|
|
555
|
-
path,
|
|
556
|
-
marks,
|
|
557
|
-
active,
|
|
558
|
-
typeEntries
|
|
559
|
-
});
|
|
560
|
-
} else if (value instanceof Set) {
|
|
561
|
-
marks.push({
|
|
562
|
-
path: [...path],
|
|
563
|
-
kind: "set"
|
|
564
|
-
});
|
|
565
|
-
encoded = encodeItems({
|
|
566
|
-
items: [...value],
|
|
567
|
-
path,
|
|
568
|
-
marks,
|
|
569
|
-
active,
|
|
570
|
-
typeEntries
|
|
571
|
-
});
|
|
572
|
-
} else if (Array.isArray(value)) encoded = encodeItems({
|
|
573
|
-
items: value,
|
|
574
|
-
path,
|
|
575
|
-
marks,
|
|
576
|
-
active,
|
|
577
|
-
typeEntries
|
|
578
|
-
});
|
|
579
|
-
else encoded = encodeRecord({
|
|
580
|
-
value,
|
|
581
|
-
path,
|
|
582
|
-
marks,
|
|
583
|
-
active,
|
|
584
|
-
typeEntries
|
|
585
|
-
});
|
|
586
|
-
active.delete(value);
|
|
587
|
-
return encoded;
|
|
588
|
-
}
|
|
589
|
-
function projectEffectTransportValue(entry, value) {
|
|
590
|
-
switch (entry.kind) {
|
|
591
|
-
case "option": return entry.matchesNone(value) ? [] : [entry.getValue(value)];
|
|
592
|
-
case "redacted": {
|
|
593
|
-
const label = entry.getLabel(value);
|
|
594
|
-
return {
|
|
595
|
-
value: entry.getValue(value),
|
|
596
|
-
...label === void 0 ? {} : { label }
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
case "chunk":
|
|
600
|
-
case "hash-set": return entry.getValues(value);
|
|
601
|
-
case "duration":
|
|
602
|
-
case "big-decimal":
|
|
603
|
-
case "date-time-utc":
|
|
604
|
-
case "date-time-zoned": return entry.format(value);
|
|
605
|
-
case "hash-map": return entry.getEntries(value);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
function encodeItems(input) {
|
|
609
|
-
const out = [];
|
|
610
|
-
for (const [index, item] of input.items.entries()) {
|
|
611
|
-
input.path.push(index);
|
|
612
|
-
const encoded = encodeValue({
|
|
613
|
-
value: item,
|
|
614
|
-
path: input.path,
|
|
615
|
-
marks: input.marks,
|
|
616
|
-
active: input.active,
|
|
617
|
-
typeEntries: input.typeEntries
|
|
618
|
-
});
|
|
619
|
-
input.path.pop();
|
|
620
|
-
if (Result.isFailure(encoded)) return encoded;
|
|
621
|
-
out.push(encoded.success);
|
|
622
|
-
}
|
|
623
|
-
return Result.succeed(out);
|
|
624
|
-
}
|
|
625
|
-
/** A Map's entries travel as an array of pairs; a pair's key and value are marked at their own paths inside it. */
|
|
626
|
-
function encodeEntries(input) {
|
|
627
|
-
return encodeItems({
|
|
628
|
-
items: input.entries.map(([key, value]) => [key, value]),
|
|
629
|
-
path: input.path,
|
|
630
|
-
marks: input.marks,
|
|
631
|
-
active: input.active,
|
|
632
|
-
typeEntries: input.typeEntries
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
/** An object's own enumerable string-keyed properties; a class instance, such as a declared error, travels as its fields. */
|
|
636
|
-
function encodeRecord(input) {
|
|
637
|
-
const out = makeNullPrototypeRecord();
|
|
638
|
-
for (const key of Object.keys(input.value)) {
|
|
639
|
-
const descriptor = Object.getOwnPropertyDescriptor(input.value, key);
|
|
640
|
-
if (descriptor === void 0 || !Object.hasOwn(descriptor, "value")) return Result.fail({
|
|
641
|
-
_tag: "UntransportableValue",
|
|
642
|
-
path: [...input.path, key],
|
|
643
|
-
reason: "an accessor property has no wire form"
|
|
644
|
-
});
|
|
645
|
-
input.path.push(key);
|
|
646
|
-
const encoded = encodeValue({
|
|
647
|
-
value: descriptor.value,
|
|
648
|
-
path: input.path,
|
|
649
|
-
marks: input.marks,
|
|
650
|
-
active: input.active,
|
|
651
|
-
typeEntries: input.typeEntries
|
|
652
|
-
});
|
|
653
|
-
input.path.pop();
|
|
654
|
-
if (Result.isFailure(encoded)) return encoded;
|
|
655
|
-
out[key] = encoded.success;
|
|
656
|
-
}
|
|
657
|
-
return Result.succeed(out);
|
|
658
|
-
}
|
|
659
|
-
function restoreAt(input) {
|
|
660
|
-
const { mark } = input;
|
|
661
|
-
function fail(reason) {
|
|
662
|
-
return Result.fail({
|
|
663
|
-
_tag: "InvalidTransportMark",
|
|
664
|
-
path: mark.path,
|
|
665
|
-
reason
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
let holder = input.root;
|
|
669
|
-
let key = "value";
|
|
670
|
-
for (const step of mark.path) {
|
|
671
|
-
const container = readOwnDataProperty({
|
|
672
|
-
holder,
|
|
673
|
-
key
|
|
674
|
-
});
|
|
675
|
-
if (Result.isFailure(container)) return fail(container.failure);
|
|
676
|
-
if (typeof container.success !== "object" || container.success === null) return fail("the marked path leaves the value");
|
|
677
|
-
holder = container.success;
|
|
678
|
-
key = step;
|
|
679
|
-
}
|
|
680
|
-
const current = readOwnDataProperty({
|
|
681
|
-
holder,
|
|
682
|
-
key
|
|
683
|
-
});
|
|
684
|
-
if (Result.isFailure(current)) return fail(current.failure);
|
|
685
|
-
const restored = restoreValue({
|
|
686
|
-
kind: mark.kind,
|
|
687
|
-
value: current.success,
|
|
688
|
-
typeEntries: input.typeEntries
|
|
689
|
-
});
|
|
690
|
-
if (Result.isFailure(restored)) return Result.fail({
|
|
691
|
-
...restored.failure,
|
|
692
|
-
path: mark.path
|
|
693
|
-
});
|
|
694
|
-
Object.defineProperty(holder, key, {
|
|
695
|
-
value: restored.success,
|
|
696
|
-
enumerable: true,
|
|
697
|
-
configurable: true,
|
|
698
|
-
writable: true
|
|
699
|
-
});
|
|
700
|
-
return Result.succeed(void 0);
|
|
701
|
-
}
|
|
702
|
-
/** A mark traverses JSON data properties, with numbers for array indices and strings for record keys. */
|
|
703
|
-
function readOwnDataProperty(input) {
|
|
704
|
-
const { holder, key } = input;
|
|
705
|
-
if (Array.isArray(holder)) {
|
|
706
|
-
if (typeof key !== "number" || !Number.isInteger(key) || key < 0 || key >= holder.length) return Result.fail("an array mark needs an existing integer index");
|
|
707
|
-
} else if (typeof key !== "string") return Result.fail("a record mark needs a string key");
|
|
708
|
-
const descriptor = Object.getOwnPropertyDescriptor(holder, key);
|
|
709
|
-
return descriptor !== void 0 && descriptor.enumerable && Object.hasOwn(descriptor, "value") ? Result.succeed(descriptor.value) : Result.fail("a mark must address an existing own data property");
|
|
710
|
-
}
|
|
711
|
-
function restoreValue(input) {
|
|
712
|
-
const { kind, value } = input;
|
|
713
|
-
function fail(reason) {
|
|
714
|
-
return Result.fail({
|
|
715
|
-
_tag: "InvalidTransportMark",
|
|
716
|
-
path: [],
|
|
717
|
-
reason
|
|
718
|
-
});
|
|
719
|
-
}
|
|
720
|
-
switch (kind) {
|
|
721
|
-
case "undefined": return value === null ? Result.succeed(void 0) : fail("an undefined mark needs null");
|
|
722
|
-
case "date": {
|
|
723
|
-
if (typeof value !== "string") return fail("a date mark needs a string");
|
|
724
|
-
const date = new Date(value);
|
|
725
|
-
return Number.isNaN(date.getTime()) ? fail("a date mark needs an ISO date") : Result.succeed(date);
|
|
726
|
-
}
|
|
727
|
-
case "bigint":
|
|
728
|
-
if (typeof value !== "string") return fail("a bigint mark needs a string");
|
|
729
|
-
return Result.try({
|
|
730
|
-
try: () => BigInt(value),
|
|
731
|
-
catch: () => {
|
|
732
|
-
return {
|
|
733
|
-
_tag: "InvalidTransportMark",
|
|
734
|
-
path: [],
|
|
735
|
-
reason: "a bigint mark needs an integer string"
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
case "number": switch (value) {
|
|
740
|
-
case "NaN": return Result.succeed(NaN);
|
|
741
|
-
case "Infinity": return Result.succeed(Number.POSITIVE_INFINITY);
|
|
742
|
-
case "-Infinity": return Result.succeed(Number.NEGATIVE_INFINITY);
|
|
743
|
-
case "-0": return Result.succeed(-0);
|
|
744
|
-
default: return fail("a number mark names NaN, Infinity, -Infinity, or -0");
|
|
745
|
-
}
|
|
746
|
-
case "url":
|
|
747
|
-
if (typeof value !== "string") return fail("a url mark needs a string");
|
|
748
|
-
return Result.try({
|
|
749
|
-
try: () => new URL(value),
|
|
750
|
-
catch: () => {
|
|
751
|
-
return {
|
|
752
|
-
_tag: "InvalidTransportMark",
|
|
753
|
-
path: [],
|
|
754
|
-
reason: "a url mark needs an absolute URL"
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
});
|
|
758
|
-
case "url-search-params": {
|
|
759
|
-
if (!Array.isArray(value)) return fail("a URLSearchParams mark needs an array of pairs");
|
|
760
|
-
const entries = [];
|
|
761
|
-
for (const pair of value) {
|
|
762
|
-
if (!Array.isArray(pair) || pair.length !== 2 || typeof pair[0] !== "string" || typeof pair[1] !== "string") return fail("a URLSearchParams mark needs an array of string pairs");
|
|
763
|
-
entries.push([pair[0], pair[1]]);
|
|
764
|
-
}
|
|
765
|
-
return Result.succeed(new URLSearchParams(entries));
|
|
766
|
-
}
|
|
767
|
-
case "regexp": {
|
|
768
|
-
if (typeof value !== "object" || value === null || !("source" in value) || !("flags" in value) || typeof value.source !== "string" || typeof value.flags !== "string") return fail("a regexp mark needs a source and flags");
|
|
769
|
-
const { source, flags } = value;
|
|
770
|
-
return Result.try({
|
|
771
|
-
try: () => new RegExp(source, flags),
|
|
772
|
-
catch: () => {
|
|
773
|
-
return {
|
|
774
|
-
_tag: "InvalidTransportMark",
|
|
775
|
-
path: [],
|
|
776
|
-
reason: "a regexp mark needs a valid pattern"
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
case "map": {
|
|
782
|
-
if (!Array.isArray(value)) return fail("a map mark needs an array of pairs");
|
|
783
|
-
const entries = [];
|
|
784
|
-
for (const pair of value) {
|
|
785
|
-
if (!Array.isArray(pair) || pair.length !== 2) return fail("a map mark needs an array of pairs");
|
|
786
|
-
entries.push([pair[0], pair[1]]);
|
|
787
|
-
}
|
|
788
|
-
return Result.succeed(new Map(entries));
|
|
789
|
-
}
|
|
790
|
-
case "set":
|
|
791
|
-
if (!Array.isArray(value)) return fail("a set mark needs an array");
|
|
792
|
-
return Result.succeed(new Set(value));
|
|
793
|
-
case "option":
|
|
794
|
-
case "redacted":
|
|
795
|
-
case "chunk":
|
|
796
|
-
case "duration":
|
|
797
|
-
case "big-decimal":
|
|
798
|
-
case "date-time-utc":
|
|
799
|
-
case "date-time-zoned":
|
|
800
|
-
case "hash-map":
|
|
801
|
-
case "hash-set": return restoreEffectTransportType({
|
|
802
|
-
kind,
|
|
803
|
-
value,
|
|
804
|
-
typeEntries: input.typeEntries
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
/** Restores one Effect data type through the boundary-specific adapter list. */
|
|
809
|
-
function restoreEffectTransportType(input) {
|
|
810
|
-
const entry = input.typeEntries.find((candidate) => {
|
|
811
|
-
return candidate.kind === input.kind;
|
|
812
|
-
});
|
|
813
|
-
if (entry === void 0) return Result.fail({
|
|
814
|
-
_tag: "InvalidTransportMark",
|
|
815
|
-
path: [],
|
|
816
|
-
reason: `${input.kind} is not part of this application's transport`
|
|
817
|
-
});
|
|
818
|
-
const restored = Result.try({
|
|
819
|
-
try: () => restoreEffectTransportValue(entry, input.value),
|
|
820
|
-
catch: (cause) => {
|
|
821
|
-
return {
|
|
822
|
-
_tag: "InvalidTransportMark",
|
|
823
|
-
path: [],
|
|
824
|
-
reason: `${input.kind} could not be restored: ${String(cause)}`
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
if (Result.isFailure(restored)) return Result.fail(restored.failure);
|
|
829
|
-
return restored.success;
|
|
830
|
-
}
|
|
831
|
-
function restoreEffectTransportValue(entry, value) {
|
|
832
|
-
function fail(reason) {
|
|
833
|
-
return Result.fail({
|
|
834
|
-
_tag: "InvalidTransportMark",
|
|
835
|
-
path: [],
|
|
836
|
-
reason
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
function restoreParsed(parsed, reason) {
|
|
840
|
-
return parsed._tag === "Some" ? Result.succeed(parsed.value) : fail(reason);
|
|
841
|
-
}
|
|
842
|
-
switch (entry.kind) {
|
|
843
|
-
case "option": return Array.isArray(value) && value.length === 0 ? Result.succeed(entry.none()) : Array.isArray(value) && value.length === 1 ? Result.succeed(entry.some(value[0])) : fail("an option mark needs an empty or one-item array");
|
|
844
|
-
case "redacted": {
|
|
845
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return fail("a redacted mark needs a value and an optional string label");
|
|
846
|
-
const record = value;
|
|
847
|
-
if (!("value" in record) || record["label"] !== void 0 && typeof record["label"] !== "string") return fail("a redacted mark needs a value and an optional string label");
|
|
848
|
-
return Result.succeed(entry.make(record["value"], record["label"]));
|
|
849
|
-
}
|
|
850
|
-
case "chunk": return Array.isArray(value) ? Result.succeed(entry.fromValues(value)) : fail("a chunk mark needs an array");
|
|
851
|
-
case "duration": return typeof value === "string" ? restoreParsed(entry.parse(value), "a duration mark needs valid duration text") : fail("a duration mark needs duration text");
|
|
852
|
-
case "big-decimal": return typeof value === "string" ? restoreParsed(entry.parse(value), "a BigDecimal mark needs valid decimal text") : fail("a BigDecimal mark needs decimal text");
|
|
853
|
-
case "date-time-utc": return typeof value === "string" ? restoreParsed(entry.parse(value), "a DateTime.Utc mark needs valid UTC ISO text") : fail("a DateTime.Utc mark needs UTC ISO text");
|
|
854
|
-
case "date-time-zoned": return typeof value === "string" ? restoreParsed(entry.parse(value), "a DateTime.Zoned mark needs valid zoned ISO text") : fail("a DateTime.Zoned mark needs zoned ISO text");
|
|
855
|
-
case "hash-map":
|
|
856
|
-
if (!Array.isArray(value) || !value.every((pair) => {
|
|
857
|
-
return Array.isArray(pair) && pair.length === 2;
|
|
858
|
-
})) return fail("a HashMap mark needs an array of pairs");
|
|
859
|
-
return Result.succeed(entry.fromEntries(value));
|
|
860
|
-
case "hash-set": return Array.isArray(value) ? Result.succeed(entry.fromValues(value)) : fail("a HashSet mark needs an array");
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
//#endregion
|
|
864
|
-
export { SEARCH_PARAMETER_PROTOCOL as S, DOCUMENT_PROTOCOL as _, restoreEffectTransportType as a, HTTP_PROTOCOL as b, compileUiPattern as c, encodeRoutePatternForMatcher as d, formatPathWireError as f, DEVELOPMENT_PROTOCOL as g, BROWSER_STATE_PROTOCOL as h, encodeTransportedValue as i, decodeMatchCaptures as l, ARTIFACT_PROTOCOL as m, TRANSPORT_MARK_KINDS as n, canonicalizeRequestPathForMatcher as o, makeNullPrototypeRecord as p, decodeTransportedValue as r, compileEndpointPattern as s, EFFECT_TRANSPORT_TYPES as t, encodePathCapture as u, FRAMEWORK_ERROR_TAGS as v, PROCESS_ENVIRONMENT_PROTOCOL as x, FRAMEWORK_IDENTITY_PROTOCOL as y };
|