@soundscript/soundscript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +10 -0
- package/async.d.ts +81 -0
- package/async.js +214 -0
- package/async.js.map +1 -0
- package/bin/soundscript.js +54 -0
- package/codec.d.ts +31 -0
- package/codec.js +31 -0
- package/codec.js.map +1 -0
- package/compare.d.ts +28 -0
- package/compare.js +121 -0
- package/compare.js.map +1 -0
- package/decode.d.ts +84 -0
- package/decode.js +249 -0
- package/decode.js.map +1 -0
- package/encode.d.ts +98 -0
- package/encode.js +128 -0
- package/encode.js.map +1 -0
- package/experimental/component.d.ts +40 -0
- package/experimental/component.js +46 -0
- package/experimental/component.js.map +1 -0
- package/experimental/css.d.ts +16 -0
- package/experimental/css.js +10 -0
- package/experimental/css.js.map +1 -0
- package/experimental/debug.d.ts +2 -0
- package/experimental/debug.js +10 -0
- package/experimental/debug.js.map +1 -0
- package/experimental/graphql.d.ts +16 -0
- package/experimental/graphql.js +10 -0
- package/experimental/graphql.js.map +1 -0
- package/experimental/sql.d.ts +22 -0
- package/experimental/sql.js +24 -0
- package/experimental/sql.js.map +1 -0
- package/failures.d.ts +23 -0
- package/failures.js +42 -0
- package/failures.js.map +1 -0
- package/hash.d.ts +34 -0
- package/hash.js +116 -0
- package/hash.js.map +1 -0
- package/hkt.d.ts +40 -0
- package/hkt.js +4 -0
- package/hkt.js.map +1 -0
- package/index.d.ts +9 -0
- package/index.js +16 -0
- package/index.js.map +1 -0
- package/json.d.ts +98 -0
- package/json.js +638 -0
- package/json.js.map +1 -0
- package/match.d.ts +11 -0
- package/match.js +14 -0
- package/match.js.map +1 -0
- package/package.json +153 -0
- package/result.d.ts +52 -0
- package/result.js +104 -0
- package/result.js.map +1 -0
- package/soundscript/async.sts +315 -0
- package/soundscript/codec.sts +75 -0
- package/soundscript/compare.sts +159 -0
- package/soundscript/decode.sts +382 -0
- package/soundscript/encode.sts +254 -0
- package/soundscript/experimental/component.sts +69 -0
- package/soundscript/experimental/css.sts +28 -0
- package/soundscript/experimental/debug.sts +10 -0
- package/soundscript/experimental/graphql.sts +28 -0
- package/soundscript/experimental/sql.sts +53 -0
- package/soundscript/failures.sts +64 -0
- package/soundscript/hash.sts +196 -0
- package/soundscript/hkt.sts +41 -0
- package/soundscript/index.sts +23 -0
- package/soundscript/json.sts +824 -0
- package/soundscript/match.sts +26 -0
- package/soundscript/result.sts +179 -0
- package/soundscript/thunk.sts +15 -0
- package/soundscript/typeclasses.sts +167 -0
- package/thunk.d.ts +2 -0
- package/thunk.js +10 -0
- package/thunk.js.map +1 -0
- package/typeclasses.d.ts +57 -0
- package/typeclasses.js +78 -0
- package/typeclasses.js.map +1 -0
package/decode.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';
|
|
2
|
+
import type { Option, Result } from '@soundscript/soundscript/result';
|
|
3
|
+
|
|
4
|
+
export type DecodePathSegment = string | number;
|
|
5
|
+
export type DecodePath = readonly DecodePathSegment[];
|
|
6
|
+
|
|
7
|
+
export class DecodeFailure extends Failure {
|
|
8
|
+
readonly path: DecodePath;
|
|
9
|
+
constructor(
|
|
10
|
+
message?: string,
|
|
11
|
+
options?: {
|
|
12
|
+
cause?: unknown;
|
|
13
|
+
path?: DecodePath;
|
|
14
|
+
trace?: readonly ErrorFrame[];
|
|
15
|
+
},
|
|
16
|
+
);
|
|
17
|
+
at(segment: DecodePathSegment): this;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface Decoder<T, E = DecodeFailure> {
|
|
21
|
+
decode(value: unknown): Result<T, E>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface OptionalDecoder<T, E = DecodeFailure> extends Decoder<T | undefined, E> {
|
|
25
|
+
readonly __soundscriptOptional: true;
|
|
26
|
+
readonly inner: Decoder<T, E>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;
|
|
30
|
+
type DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;
|
|
31
|
+
type ObjectShape = Record<string, Decoder<unknown, unknown>>;
|
|
32
|
+
type TupleShape = readonly Decoder<unknown, unknown>[];
|
|
33
|
+
|
|
34
|
+
export const string: Decoder<string>;
|
|
35
|
+
export const number: Decoder<number>;
|
|
36
|
+
export const boolean: Decoder<boolean>;
|
|
37
|
+
export const bigint: Decoder<bigint>;
|
|
38
|
+
export function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E>;
|
|
39
|
+
|
|
40
|
+
export function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E>;
|
|
41
|
+
export function literal<const T extends string | number | boolean | null>(value: T): Decoder<T>;
|
|
42
|
+
export function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure>;
|
|
43
|
+
export function tuple<const TElements extends TupleShape>(
|
|
44
|
+
...elements: TElements
|
|
45
|
+
): Decoder<
|
|
46
|
+
{ readonly [K in keyof TElements]: DecoderValue<TElements[K]> },
|
|
47
|
+
DecoderError<TElements[number]> | DecodeFailure
|
|
48
|
+
>;
|
|
49
|
+
export function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure>;
|
|
50
|
+
export function result<T, EValue, EDecodeValue, EDecodeError>(
|
|
51
|
+
okDecoder: Decoder<T, EDecodeValue>,
|
|
52
|
+
errDecoder: Decoder<EValue, EDecodeError>,
|
|
53
|
+
): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure>;
|
|
54
|
+
export function object<TShape extends ObjectShape>(
|
|
55
|
+
shape: TShape,
|
|
56
|
+
): Decoder<
|
|
57
|
+
{ readonly [K in keyof TShape]: DecoderValue<TShape[K]> },
|
|
58
|
+
DecoderError<TShape[keyof TShape]> | DecodeFailure
|
|
59
|
+
>;
|
|
60
|
+
export function field<K extends string, T, E>(
|
|
61
|
+
key: K,
|
|
62
|
+
decoder: Decoder<T, E>,
|
|
63
|
+
): Decoder<T, E | DecodeFailure>;
|
|
64
|
+
export function optionalField<K extends string, T, E>(
|
|
65
|
+
key: K,
|
|
66
|
+
decoder: Decoder<T, E>,
|
|
67
|
+
): Decoder<T | undefined, E | DecodeFailure>;
|
|
68
|
+
export function union<A, B, ELeft, ERight>(
|
|
69
|
+
left: Decoder<A, ELeft>,
|
|
70
|
+
right: Decoder<B, ERight>,
|
|
71
|
+
): Decoder<A | B, ELeft | ERight | DecodeFailure>;
|
|
72
|
+
export function map<A, B, E>(
|
|
73
|
+
decoder: Decoder<A, E>,
|
|
74
|
+
project: (value: A) => B,
|
|
75
|
+
): Decoder<B, E>;
|
|
76
|
+
export function andThen<A, B, E>(
|
|
77
|
+
decoder: Decoder<A, E>,
|
|
78
|
+
project: (value: A) => Decoder<B, E>,
|
|
79
|
+
): Decoder<B, E>;
|
|
80
|
+
export function refine<A, B extends A, E>(
|
|
81
|
+
decoder: Decoder<A, E>,
|
|
82
|
+
predicate: (value: A) => value is B,
|
|
83
|
+
message: string,
|
|
84
|
+
): Decoder<B, E | DecodeFailure>;
|
package/decode.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { Failure } from '@soundscript/soundscript/failures';
|
|
2
|
+
import { err, isErr, ok } from '@soundscript/soundscript/result';
|
|
3
|
+
export class DecodeFailure extends Failure {
|
|
4
|
+
constructor(message = 'Failed to decode value.', options = {}) {
|
|
5
|
+
super(message, { cause: options.cause, trace: options.trace });
|
|
6
|
+
this.path = options.path ?? [];
|
|
7
|
+
}
|
|
8
|
+
at(segment) {
|
|
9
|
+
const prototype = Object.getPrototypeOf(this);
|
|
10
|
+
const clone = (prototype === null ? Object.create(null) : Object.create(prototype));
|
|
11
|
+
Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));
|
|
12
|
+
Object.defineProperty(clone, 'path', {
|
|
13
|
+
configurable: true,
|
|
14
|
+
enumerable: true,
|
|
15
|
+
writable: false,
|
|
16
|
+
value: [segment, ...this.path],
|
|
17
|
+
});
|
|
18
|
+
return clone;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const string = {
|
|
22
|
+
decode(value) {
|
|
23
|
+
return typeof value === 'string'
|
|
24
|
+
? ok(value)
|
|
25
|
+
: err(new DecodeFailure('Expected string.', { cause: value }));
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export const number = {
|
|
29
|
+
decode(value) {
|
|
30
|
+
return typeof value === 'number'
|
|
31
|
+
? ok(value)
|
|
32
|
+
: err(new DecodeFailure('Expected number.', { cause: value }));
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
export const boolean = {
|
|
36
|
+
decode(value) {
|
|
37
|
+
return typeof value === 'boolean'
|
|
38
|
+
? ok(value)
|
|
39
|
+
: err(new DecodeFailure('Expected boolean.', { cause: value }));
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const bigint = {
|
|
43
|
+
decode(value) {
|
|
44
|
+
if (typeof value === 'bigint') {
|
|
45
|
+
return ok(value);
|
|
46
|
+
}
|
|
47
|
+
if (typeof value === 'number') {
|
|
48
|
+
return Number.isInteger(value) && Number.isSafeInteger(value)
|
|
49
|
+
? ok(BigInt(value))
|
|
50
|
+
: err(new DecodeFailure('Expected bigint.', { cause: value }));
|
|
51
|
+
}
|
|
52
|
+
if (typeof value === 'string') {
|
|
53
|
+
try {
|
|
54
|
+
return ok(BigInt(value));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return err(new DecodeFailure('Expected bigint.', { cause: value }));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return err(new DecodeFailure('Expected bigint.', { cause: value }));
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
export function lazy(getDecoder) {
|
|
64
|
+
return {
|
|
65
|
+
decode(value) {
|
|
66
|
+
return getDecoder().decode(value);
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function optional(decoder) {
|
|
71
|
+
return {
|
|
72
|
+
__soundscriptOptional: true,
|
|
73
|
+
inner: decoder,
|
|
74
|
+
decode(value) {
|
|
75
|
+
return value === undefined ? ok(undefined) : decoder.decode(value);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function literal(value) {
|
|
80
|
+
return {
|
|
81
|
+
decode(input) {
|
|
82
|
+
return Object.is(input, value)
|
|
83
|
+
? ok(value)
|
|
84
|
+
: err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function array(item) {
|
|
89
|
+
return {
|
|
90
|
+
decode(value) {
|
|
91
|
+
if (!Array.isArray(value)) {
|
|
92
|
+
return err(new DecodeFailure('Expected array.', { cause: value }));
|
|
93
|
+
}
|
|
94
|
+
const decodedValues = [];
|
|
95
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
96
|
+
const decoded = item.decode(value[index]);
|
|
97
|
+
if (isErr(decoded)) {
|
|
98
|
+
return err(prependPathIfPossible(decoded.error, index));
|
|
99
|
+
}
|
|
100
|
+
decodedValues.push(decoded.value);
|
|
101
|
+
}
|
|
102
|
+
return ok(decodedValues);
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function tuple(...elements) {
|
|
107
|
+
return {
|
|
108
|
+
decode(value) {
|
|
109
|
+
if (!Array.isArray(value)) {
|
|
110
|
+
return err(new DecodeFailure('Expected tuple.', { cause: value }));
|
|
111
|
+
}
|
|
112
|
+
if (value.length !== elements.length) {
|
|
113
|
+
return err(new DecodeFailure(`Expected tuple of length ${elements.length}.`, {
|
|
114
|
+
cause: value,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
const decodedValues = [];
|
|
118
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
119
|
+
const elementDecoder = elements[index];
|
|
120
|
+
if (!elementDecoder) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const decoded = elementDecoder.decode(value[index]);
|
|
124
|
+
if (isErr(decoded)) {
|
|
125
|
+
return err(prependPathIfPossible(decoded.error, index));
|
|
126
|
+
}
|
|
127
|
+
decodedValues.push(decoded.value);
|
|
128
|
+
}
|
|
129
|
+
return ok(decodedValues);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export function option(item) {
|
|
134
|
+
return union(map(object({
|
|
135
|
+
tag: literal('ok'),
|
|
136
|
+
value: item,
|
|
137
|
+
}), (value) => ok(value.value)), map(object({
|
|
138
|
+
tag: literal('err'),
|
|
139
|
+
}), () => err()));
|
|
140
|
+
}
|
|
141
|
+
export function result(okDecoder, errDecoder) {
|
|
142
|
+
return union(map(object({
|
|
143
|
+
tag: literal('ok'),
|
|
144
|
+
value: okDecoder,
|
|
145
|
+
}), (value) => ok(value.value)), map(object({
|
|
146
|
+
tag: literal('err'),
|
|
147
|
+
error: errDecoder,
|
|
148
|
+
}), (value) => err(value.error)));
|
|
149
|
+
}
|
|
150
|
+
export function object(shape) {
|
|
151
|
+
return {
|
|
152
|
+
decode(value) {
|
|
153
|
+
if (!isPlainObject(value)) {
|
|
154
|
+
return err(new DecodeFailure('Expected object.', { cause: value }));
|
|
155
|
+
}
|
|
156
|
+
const record = value;
|
|
157
|
+
const decodedObject = {};
|
|
158
|
+
for (const key of Object.keys(shape)) {
|
|
159
|
+
const decoder = shape[key];
|
|
160
|
+
const hasKey = key in record;
|
|
161
|
+
const rawValue = record[key];
|
|
162
|
+
if (!hasKey || rawValue === undefined) {
|
|
163
|
+
if (isOptionalDecoder(decoder)) {
|
|
164
|
+
decodedObject[key] = undefined;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
return err(new DecodeFailure(`Missing field "${key}".`, {
|
|
168
|
+
cause: value,
|
|
169
|
+
path: [key],
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
const decoded = decoder.decode(rawValue);
|
|
173
|
+
if (isErr(decoded)) {
|
|
174
|
+
return err(prependPathIfPossible(decoded.error, key));
|
|
175
|
+
}
|
|
176
|
+
decodedObject[key] = decoded.value;
|
|
177
|
+
}
|
|
178
|
+
return ok(decodedObject);
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export function field(key, decoder) {
|
|
183
|
+
const shape = { [key]: decoder };
|
|
184
|
+
return map(object(shape), (value) => value[key]);
|
|
185
|
+
}
|
|
186
|
+
export function optionalField(key, decoder) {
|
|
187
|
+
const shape = { [key]: optional(decoder) };
|
|
188
|
+
return map(object(shape), (value) => value[key]);
|
|
189
|
+
}
|
|
190
|
+
export function union(left, right) {
|
|
191
|
+
return {
|
|
192
|
+
decode(value) {
|
|
193
|
+
const leftDecoded = left.decode(value);
|
|
194
|
+
if (isErr(leftDecoded)) {
|
|
195
|
+
const rightDecoded = right.decode(value);
|
|
196
|
+
if (isErr(rightDecoded)) {
|
|
197
|
+
return err(new DecodeFailure('Expected one of the union members.', {
|
|
198
|
+
cause: value,
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
return rightDecoded;
|
|
202
|
+
}
|
|
203
|
+
return leftDecoded;
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
export function map(decoder, project) {
|
|
208
|
+
return {
|
|
209
|
+
decode(value) {
|
|
210
|
+
const decoded = decoder.decode(value);
|
|
211
|
+
return isErr(decoded) ? decoded : ok(project(decoded.value));
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export function andThen(decoder, project) {
|
|
216
|
+
return {
|
|
217
|
+
decode(value) {
|
|
218
|
+
const decoded = decoder.decode(value);
|
|
219
|
+
return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
export function refine(decoder, predicate, message) {
|
|
224
|
+
return {
|
|
225
|
+
decode(value) {
|
|
226
|
+
const decoded = decoder.decode(value);
|
|
227
|
+
if (isErr(decoded)) {
|
|
228
|
+
return decoded;
|
|
229
|
+
}
|
|
230
|
+
return predicate(decoded.value)
|
|
231
|
+
? ok(decoded.value)
|
|
232
|
+
: err(new DecodeFailure(message, { cause: value }));
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function prependPathIfPossible(error, segment) {
|
|
237
|
+
return error instanceof DecodeFailure ? error.at(segment) : error;
|
|
238
|
+
}
|
|
239
|
+
function isOptionalDecoder(value) {
|
|
240
|
+
return '__soundscriptOptional' in value &&
|
|
241
|
+
value.__soundscriptOptional === true;
|
|
242
|
+
}
|
|
243
|
+
function isPlainObject(value) {
|
|
244
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
245
|
+
}
|
|
246
|
+
function valueOf(decoded) {
|
|
247
|
+
return decoded.value;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=decode.js.map
|
package/decode.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["./soundscript/decode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, ok, type Option, type Result } from '@soundscript/soundscript/result';\n\nexport type DecodePathSegment = string | number;\nexport type DecodePath = readonly DecodePathSegment[];\n\nexport class DecodeFailure extends Failure {\n readonly path: DecodePath;\n\n constructor(\n message = 'Failed to decode value.',\n options: {\n cause?: unknown;\n path?: DecodePath;\n trace?: readonly ErrorFrame[];\n } = {},\n ) {\n super(message, { cause: options.cause, trace: options.trace });\n this.path = options.path ?? [];\n }\n\n at(segment: DecodePathSegment): this {\n const prototype = Object.getPrototypeOf(this as object);\n const clone = (prototype === null ? Object.create(null) : Object.create(prototype)) as this;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));\n Object.defineProperty(clone, 'path', {\n configurable: true,\n enumerable: true,\n writable: false,\n value: [segment, ...this.path],\n });\n return clone;\n }\n}\n\nexport interface Decoder<T, E = DecodeFailure> {\n decode(value: unknown): Result<T, E>;\n}\n\nexport interface OptionalDecoder<T, E = DecodeFailure> extends Decoder<T | undefined, E> {\n readonly __soundscriptOptional: true;\n readonly inner: Decoder<T, E>;\n}\n\ntype DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;\ntype DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;\n\ntype ObjectShape = Record<string, Decoder<unknown, unknown>>;\ntype TupleShape = readonly Decoder<unknown, unknown>[];\n\nexport const string: Decoder<string> = {\n decode(value) {\n return typeof value === 'string'\n ? ok(value)\n : err(new DecodeFailure('Expected string.', { cause: value }));\n },\n};\n\nexport const number: Decoder<number> = {\n decode(value) {\n return typeof value === 'number'\n ? ok(value)\n : err(new DecodeFailure('Expected number.', { cause: value }));\n },\n};\n\nexport const boolean: Decoder<boolean> = {\n decode(value) {\n return typeof value === 'boolean'\n ? ok(value)\n : err(new DecodeFailure('Expected boolean.', { cause: value }));\n },\n};\n\nexport const bigint: Decoder<bigint> = {\n decode(value) {\n if (typeof value === 'bigint') {\n return ok(value);\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) && Number.isSafeInteger(value)\n ? ok(BigInt(value))\n : err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n\n if (typeof value === 'string') {\n try {\n return ok(BigInt(value));\n } catch {\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n }\n\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n },\n};\n\nexport function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E> {\n return {\n decode(value) {\n return getDecoder().decode(value);\n },\n };\n}\n\nexport function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E> {\n return {\n __soundscriptOptional: true,\n inner: decoder,\n decode(value) {\n return value === undefined ? ok(undefined) : decoder.decode(value);\n },\n };\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Decoder<T> {\n return {\n decode(input) {\n return Object.is(input, value)\n ? ok(value)\n : err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));\n },\n };\n}\n\nexport function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected array.', { cause: value }));\n }\n\n const decodedValues: T[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const decoded = item.decode(value[index]);\n if (isErr(decoded)) {\n return err(prependPathIfPossible(decoded.error, index));\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues);\n },\n };\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Decoder<\n { readonly [K in keyof TElements]: DecoderValue<TElements[K]> },\n DecoderError<TElements[number]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected tuple.', { cause: value }));\n }\n\n if (value.length !== elements.length) {\n return err(\n new DecodeFailure(`Expected tuple of length ${elements.length}.`, {\n cause: value,\n }),\n );\n }\n\n const decodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementDecoder = elements[index];\n if (!elementDecoder) {\n continue;\n }\n const decoded = elementDecoder.decode(value[index]);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, index) as\n | DecoderError<TElements[number]>\n | DecodeFailure,\n );\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues as { readonly [K in keyof TElements]: DecoderValue<TElements[K]> });\n },\n };\n}\n\nexport function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: item,\n }),\n (value) => ok(value.value) as Option<T>,\n ),\n map(\n object({\n tag: literal('err'),\n }),\n () => err() as Option<T>,\n ),\n );\n}\n\nexport function result<T, EValue, EDecodeValue, EDecodeError>(\n okDecoder: Decoder<T, EDecodeValue>,\n errDecoder: Decoder<EValue, EDecodeError>,\n): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: okDecoder,\n }),\n (value) => ok(value.value) as Result<T, EValue>,\n ),\n map(\n object({\n tag: literal('err'),\n error: errDecoder,\n }),\n (value) => err(value.error) as Result<T, EValue>,\n ),\n );\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Decoder<\n { readonly [K in keyof TShape]: DecoderValue<TShape[K]> },\n DecoderError<TShape[keyof TShape]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!isPlainObject(value)) {\n return err(new DecodeFailure('Expected object.', { cause: value }));\n }\n\n const record = value as Record<string, unknown>;\n const decodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const decoder = shape[key];\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalDecoder(decoder)) {\n decodedObject[key] = undefined;\n continue;\n }\n\n return err(\n new DecodeFailure(`Missing field \"${key}\".`, {\n cause: value,\n path: [key],\n }),\n );\n }\n\n const decoded = decoder.decode(rawValue);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, key) as\n | DecoderError<TShape[keyof TShape]>\n | DecodeFailure,\n );\n }\n\n decodedObject[key] = decoded.value;\n }\n\n return ok(decodedObject as { readonly [K in keyof TShape]: DecoderValue<TShape[K]> });\n },\n };\n}\n\nexport function field<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T, E | DecodeFailure> {\n const shape = { [key]: decoder } as { readonly [P in K]: Decoder<T, E> };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function optionalField<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T | undefined, E | DecodeFailure> {\n const shape = { [key]: optional(decoder) } as {\n readonly [P in K]: OptionalDecoder<T, E>;\n };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function union<A, B, ELeft, ERight>(\n left: Decoder<A, ELeft>,\n right: Decoder<B, ERight>,\n): Decoder<A | B, ELeft | ERight | DecodeFailure> {\n return {\n decode(value) {\n const leftDecoded = left.decode(value);\n if (isErr(leftDecoded)) {\n const rightDecoded = right.decode(value);\n if (isErr(rightDecoded)) {\n return err(\n new DecodeFailure('Expected one of the union members.', {\n cause: value,\n }),\n );\n }\n return rightDecoded;\n }\n return leftDecoded;\n },\n };\n}\n\nexport function map<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => B,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : ok(project(decoded.value));\n },\n };\n}\n\nexport function andThen<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => Decoder<B, E>,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));\n },\n };\n}\n\nexport function refine<A, B extends A, E>(\n decoder: Decoder<A, E>,\n predicate: (value: A) => value is B,\n message: string,\n): Decoder<B, E | DecodeFailure> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n if (isErr(decoded)) {\n return decoded;\n }\n\n return predicate(decoded.value)\n ? ok(decoded.value)\n : err(new DecodeFailure(message, { cause: value }));\n },\n };\n}\n\nfunction prependPathIfPossible<E>(error: E, segment: DecodePathSegment): E | DecodeFailure {\n return error instanceof DecodeFailure ? error.at(segment) : error;\n}\n\nfunction isOptionalDecoder(\n value: Decoder<unknown, unknown>,\n): value is OptionalDecoder<unknown, unknown> {\n return '__soundscriptOptional' in value &&\n value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction valueOf<T>(decoded: { readonly value: T }): T {\n return decoded.value;\n}\n"]}
|
package/encode.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Bind, Kind3, TypeLambda } from '@soundscript/soundscript/hkt';
|
|
2
|
+
import { Failure } from '@soundscript/soundscript/failures';
|
|
3
|
+
import type { Option, Result } from '@soundscript/soundscript/result';
|
|
4
|
+
import type { Contravariant } from '@soundscript/soundscript/typeclasses';
|
|
5
|
+
|
|
6
|
+
export class EncodeFailure extends Failure {
|
|
7
|
+
constructor(message?: string, cause?: unknown);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Encoder<T, TEncoded = unknown, E = EncodeFailure> {
|
|
11
|
+
encode(value: T): Result<TEncoded, E>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface OptionalEncoder<T, TEncoded = T, E = EncodeFailure>
|
|
15
|
+
extends Encoder<T | undefined, TEncoded | undefined, E> {
|
|
16
|
+
readonly __soundscriptOptional: true;
|
|
17
|
+
readonly inner: Encoder<T, TEncoded, E>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type EncoderInput<TEncoder> = TEncoder extends Encoder<infer TValue, unknown, unknown> ? TValue
|
|
21
|
+
: never;
|
|
22
|
+
type EncoderOutput<TEncoder> = TEncoder extends Encoder<unknown, infer TEncoded, unknown>
|
|
23
|
+
? TEncoded
|
|
24
|
+
: never;
|
|
25
|
+
type EncoderError<TEncoder> = TEncoder extends Encoder<unknown, unknown, infer E> ? E : never;
|
|
26
|
+
type ObjectShape = Record<string, Encoder<unknown, unknown, unknown>>;
|
|
27
|
+
type TupleShape = readonly Encoder<unknown, unknown, unknown>[];
|
|
28
|
+
|
|
29
|
+
export interface EncoderF extends TypeLambda {
|
|
30
|
+
readonly type: Encoder<this['Args'][2], this['Args'][1], this['Args'][0]>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type EncoderKind<E, TEncoded, T> = Kind3<EncoderF, E, TEncoded, T>;
|
|
34
|
+
|
|
35
|
+
export function fromEncode<T, TEncoded, E>(
|
|
36
|
+
encode: (value: T) => Result<TEncoded, E>,
|
|
37
|
+
): Encoder<T, TEncoded, E>;
|
|
38
|
+
export function contramap<A, B, TEncoded, E>(
|
|
39
|
+
encoder: Encoder<A, TEncoded, E>,
|
|
40
|
+
project: (value: B) => A,
|
|
41
|
+
): Encoder<B, TEncoded, E>;
|
|
42
|
+
export function encoderContravariant<TEncoded, E = EncodeFailure>(): Contravariant<
|
|
43
|
+
Bind<Bind<EncoderF, [E]>, [TEncoded]>
|
|
44
|
+
>;
|
|
45
|
+
|
|
46
|
+
export const stringEncoder: Encoder<string, string>;
|
|
47
|
+
export const numberEncoder: Encoder<number, number>;
|
|
48
|
+
export const booleanEncoder: Encoder<boolean, boolean>;
|
|
49
|
+
export const bigintEncoder: Encoder<bigint, bigint>;
|
|
50
|
+
|
|
51
|
+
export function optional<T, TEncoded, E>(
|
|
52
|
+
encoder: Encoder<T, TEncoded, E>,
|
|
53
|
+
): OptionalEncoder<T, TEncoded, E>;
|
|
54
|
+
export function lazy<T, TEncoded, E>(
|
|
55
|
+
getEncoder: () => Encoder<T, TEncoded, E>,
|
|
56
|
+
): Encoder<T, TEncoded, E>;
|
|
57
|
+
export function nullable<T, TEncoded, E>(
|
|
58
|
+
encoder: Encoder<T, TEncoded, E>,
|
|
59
|
+
): Encoder<T | null, TEncoded | null, E>;
|
|
60
|
+
export function literal<const T extends string | number | boolean | null>(value: T): Encoder<T, T>;
|
|
61
|
+
export function array<T, TEncoded, E>(
|
|
62
|
+
item: Encoder<T, TEncoded, E>,
|
|
63
|
+
): Encoder<readonly T[], readonly TEncoded[], E | EncodeFailure>;
|
|
64
|
+
export function tuple<const TElements extends TupleShape>(
|
|
65
|
+
...elements: TElements
|
|
66
|
+
): Encoder<
|
|
67
|
+
{ readonly [K in keyof TElements]: EncoderInput<TElements[K]> },
|
|
68
|
+
{ readonly [K in keyof TElements]: EncoderOutput<TElements[K]> },
|
|
69
|
+
EncoderError<TElements[number]>
|
|
70
|
+
>;
|
|
71
|
+
export function option<T, TEncoded, E>(
|
|
72
|
+
item: Encoder<T, TEncoded, E>,
|
|
73
|
+
): Encoder<
|
|
74
|
+
Option<T>,
|
|
75
|
+
{ readonly error?: undefined; readonly tag: 'err' } | {
|
|
76
|
+
readonly tag: 'ok';
|
|
77
|
+
readonly value: TEncoded;
|
|
78
|
+
},
|
|
79
|
+
E
|
|
80
|
+
>;
|
|
81
|
+
export function result<T, EValue, TEncoded, EEncoded, EOk, EErr>(
|
|
82
|
+
okEncoder: Encoder<T, TEncoded, EOk>,
|
|
83
|
+
errEncoder: Encoder<EValue, EEncoded, EErr>,
|
|
84
|
+
): Encoder<
|
|
85
|
+
Result<T, EValue>,
|
|
86
|
+
{ readonly tag: 'ok'; readonly value: TEncoded } | {
|
|
87
|
+
readonly error: EEncoded;
|
|
88
|
+
readonly tag: 'err';
|
|
89
|
+
},
|
|
90
|
+
EOk | EErr
|
|
91
|
+
>;
|
|
92
|
+
export function object<TShape extends ObjectShape>(
|
|
93
|
+
shape: TShape,
|
|
94
|
+
): Encoder<
|
|
95
|
+
{ readonly [K in keyof TShape]: EncoderInput<TShape[K]> },
|
|
96
|
+
{ readonly [K in keyof TShape]: EncoderOutput<TShape[K]> },
|
|
97
|
+
EncoderError<TShape[keyof TShape]> | EncodeFailure
|
|
98
|
+
>;
|
package/encode.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Failure } from '@soundscript/soundscript/failures';
|
|
2
|
+
import { err, isErr, ok } from '@soundscript/soundscript/result';
|
|
3
|
+
export class EncodeFailure extends Failure {
|
|
4
|
+
constructor(message = 'Failed to encode value.', cause) {
|
|
5
|
+
super(message, { cause });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function fromEncode(encode) {
|
|
9
|
+
return {
|
|
10
|
+
encode,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function contramap(encoder, project) {
|
|
14
|
+
return fromEncode((value) => encoder.encode(project(value)));
|
|
15
|
+
}
|
|
16
|
+
export function encoderContravariant() {
|
|
17
|
+
return {
|
|
18
|
+
contramap,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export const stringEncoder = fromEncode((value) => ok(value));
|
|
22
|
+
export const numberEncoder = fromEncode((value) => ok(value));
|
|
23
|
+
export const booleanEncoder = fromEncode((value) => ok(value));
|
|
24
|
+
export const bigintEncoder = fromEncode((value) => ok(value));
|
|
25
|
+
export function optional(encoder) {
|
|
26
|
+
return {
|
|
27
|
+
__soundscriptOptional: true,
|
|
28
|
+
inner: encoder,
|
|
29
|
+
encode(value) {
|
|
30
|
+
return value === undefined ? ok(undefined) : encoder.encode(value);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function lazy(getEncoder) {
|
|
35
|
+
return fromEncode((value) => getEncoder().encode(value));
|
|
36
|
+
}
|
|
37
|
+
export function nullable(encoder) {
|
|
38
|
+
return fromEncode((value) => value === null ? ok(null) : encoder.encode(value));
|
|
39
|
+
}
|
|
40
|
+
export function literal(value) {
|
|
41
|
+
return fromEncode((input) => Object.is(input, value)
|
|
42
|
+
? ok(value)
|
|
43
|
+
: err(new EncodeFailure(`Expected literal ${JSON.stringify(value)}.`, input)));
|
|
44
|
+
}
|
|
45
|
+
export function array(item) {
|
|
46
|
+
return fromEncode((value) => {
|
|
47
|
+
const encodedValues = [];
|
|
48
|
+
for (const entry of value) {
|
|
49
|
+
const encoded = item.encode(entry);
|
|
50
|
+
if (isErr(encoded)) {
|
|
51
|
+
return encoded;
|
|
52
|
+
}
|
|
53
|
+
encodedValues.push(encoded.value);
|
|
54
|
+
}
|
|
55
|
+
return ok(encodedValues);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function tuple(...elements) {
|
|
59
|
+
return fromEncode((value) => {
|
|
60
|
+
const values = value;
|
|
61
|
+
const encodedValues = [];
|
|
62
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
63
|
+
const elementEncoder = elements[index];
|
|
64
|
+
if (!elementEncoder) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const encoded = elementEncoder.encode(values[index]);
|
|
68
|
+
if (isErr(encoded)) {
|
|
69
|
+
return encoded;
|
|
70
|
+
}
|
|
71
|
+
encodedValues.push(encoded.value);
|
|
72
|
+
}
|
|
73
|
+
return ok(encodedValues);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function option(item) {
|
|
77
|
+
return fromEncode((value) => {
|
|
78
|
+
if (value.tag === 'ok') {
|
|
79
|
+
const encoded = item.encode(value.value);
|
|
80
|
+
return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });
|
|
81
|
+
}
|
|
82
|
+
return ok({ tag: 'err', error: undefined });
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export function result(okEncoder, errEncoder) {
|
|
86
|
+
return fromEncode((value) => {
|
|
87
|
+
if (value.tag === 'ok') {
|
|
88
|
+
const encoded = okEncoder.encode(value.value);
|
|
89
|
+
return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });
|
|
90
|
+
}
|
|
91
|
+
const encoded = errEncoder.encode(value.error);
|
|
92
|
+
return isErr(encoded) ? encoded : ok({ tag: 'err', error: encoded.value });
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
export function object(shape) {
|
|
96
|
+
return fromEncode((value) => {
|
|
97
|
+
if (!isPlainObject(value)) {
|
|
98
|
+
return err(new EncodeFailure('Expected object.', value));
|
|
99
|
+
}
|
|
100
|
+
const record = value;
|
|
101
|
+
const encodedObject = {};
|
|
102
|
+
for (const key of Object.keys(shape)) {
|
|
103
|
+
const encoder = shape[key];
|
|
104
|
+
const hasKey = key in record;
|
|
105
|
+
const rawValue = record[key];
|
|
106
|
+
if (!hasKey || rawValue === undefined) {
|
|
107
|
+
if (isOptionalEncoder(encoder)) {
|
|
108
|
+
encodedObject[key] = undefined;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
return err(new EncodeFailure(`Missing field "${key}".`, value));
|
|
112
|
+
}
|
|
113
|
+
const encoded = encoder.encode(rawValue);
|
|
114
|
+
if (isErr(encoded)) {
|
|
115
|
+
return encoded;
|
|
116
|
+
}
|
|
117
|
+
encodedObject[key] = encoded.value;
|
|
118
|
+
}
|
|
119
|
+
return ok(encodedObject);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function isOptionalEncoder(value) {
|
|
123
|
+
return '__soundscriptOptional' in value && value.__soundscriptOptional === true;
|
|
124
|
+
}
|
|
125
|
+
function isPlainObject(value) {
|
|
126
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=encode.js.map
|
package/encode.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.js","sourceRoot":"","sources":["./soundscript/encode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type Bind, type Kind3, type TypeLambda } from '@soundscript/soundscript/hkt';\nimport { Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, ok, type Option, type Result } from '@soundscript/soundscript/result';\nimport type { Contravariant } from '@soundscript/soundscript/typeclasses';\n\nexport class EncodeFailure extends Failure {\n constructor(message = 'Failed to encode value.', cause?: unknown) {\n super(message, { cause });\n }\n}\n\nexport interface Encoder<T, TEncoded = unknown, E = EncodeFailure> {\n encode(value: T): Result<TEncoded, E>;\n}\n\nexport interface OptionalEncoder<T, TEncoded = T, E = EncodeFailure>\n extends Encoder<T | undefined, TEncoded | undefined, E> {\n readonly __soundscriptOptional: true;\n readonly inner: Encoder<T, TEncoded, E>;\n}\n\ntype EncoderInput<TEncoder> = TEncoder extends Encoder<infer T, unknown, unknown> ? T : never;\ntype EncoderOutput<TEncoder> = TEncoder extends Encoder<unknown, infer TEncoded, unknown> ? TEncoded\n : never;\ntype EncoderError<TEncoder> = TEncoder extends Encoder<unknown, unknown, infer E> ? E : never;\ntype ObjectShape = Record<string, Encoder<unknown, unknown, unknown>>;\ntype TupleShape = readonly Encoder<unknown, unknown, unknown>[];\n\nexport interface EncoderF extends TypeLambda {\n readonly type: Encoder<this['Args'][2], this['Args'][1], this['Args'][0]>;\n}\n\nexport type EncoderKind<E, TEncoded, T> = Kind3<EncoderF, E, TEncoded, T>;\n\nexport function fromEncode<T, TEncoded, E>(\n encode: (value: T) => Result<TEncoded, E>,\n): Encoder<T, TEncoded, E> {\n return {\n encode,\n };\n}\n\nexport function contramap<A, B, TEncoded, E>(\n encoder: Encoder<A, TEncoded, E>,\n project: (value: B) => A,\n): Encoder<B, TEncoded, E> {\n return fromEncode((value) => encoder.encode(project(value)));\n}\n\nexport function encoderContravariant<TEncoded, E = EncodeFailure>(): Contravariant<\n Bind<Bind<EncoderF, [E]>, [TEncoded]>\n> {\n return {\n contramap,\n };\n}\n\nexport const stringEncoder: Encoder<string, string> = fromEncode((value) => ok(value));\nexport const numberEncoder: Encoder<number, number> = fromEncode((value) => ok(value));\nexport const booleanEncoder: Encoder<boolean, boolean> = fromEncode((value) => ok(value));\nexport const bigintEncoder: Encoder<bigint, bigint> = fromEncode((value) => ok(value));\n\nexport function optional<T, TEncoded, E>(\n encoder: Encoder<T, TEncoded, E>,\n): OptionalEncoder<T, TEncoded, E> {\n return {\n __soundscriptOptional: true,\n inner: encoder,\n encode(value) {\n return value === undefined ? ok(undefined) : encoder.encode(value);\n },\n };\n}\n\nexport function lazy<T, TEncoded, E>(\n getEncoder: () => Encoder<T, TEncoded, E>,\n): Encoder<T, TEncoded, E> {\n return fromEncode((value) => getEncoder().encode(value));\n}\n\nexport function nullable<T, TEncoded, E>(\n encoder: Encoder<T, TEncoded, E>,\n): Encoder<T | null, TEncoded | null, E> {\n return fromEncode((value) => value === null ? ok(null) : encoder.encode(value));\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Encoder<T, T> {\n return fromEncode((input) =>\n Object.is(input, value)\n ? ok(value)\n : err(new EncodeFailure(`Expected literal ${JSON.stringify(value)}.`, input))\n );\n}\n\nexport function array<T, TEncoded, E>(\n item: Encoder<T, TEncoded, E>,\n): Encoder<readonly T[], readonly TEncoded[], E | EncodeFailure> {\n return fromEncode((value) => {\n const encodedValues: TEncoded[] = [];\n for (const entry of value) {\n const encoded = item.encode(entry);\n if (isErr(encoded)) {\n return encoded;\n }\n encodedValues.push(encoded.value);\n }\n return ok(encodedValues);\n });\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Encoder<\n { readonly [K in keyof TElements]: EncoderInput<TElements[K]> },\n { readonly [K in keyof TElements]: EncoderOutput<TElements[K]> },\n EncoderError<TElements[number]>\n> {\n return fromEncode((value) => {\n const values = value as readonly unknown[];\n const encodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementEncoder = elements[index];\n if (!elementEncoder) {\n continue;\n }\n const encoded = elementEncoder.encode(values[index] as never);\n if (isErr(encoded)) {\n return encoded as Result<\n { readonly [K in keyof TElements]: EncoderOutput<TElements[K]> },\n EncoderError<TElements[number]>\n >;\n }\n encodedValues.push(encoded.value);\n }\n return ok(encodedValues as { readonly [K in keyof TElements]: EncoderOutput<TElements[K]> });\n });\n}\n\nexport function option<T, TEncoded, E>(\n item: Encoder<T, TEncoded, E>,\n): Encoder<\n Option<T>,\n { readonly error?: undefined; readonly tag: 'err' } | {\n readonly tag: 'ok';\n readonly value: TEncoded;\n },\n E\n> {\n return fromEncode<\n Option<T>,\n { readonly error?: undefined; readonly tag: 'err' } | {\n readonly tag: 'ok';\n readonly value: TEncoded;\n },\n E\n >((value) => {\n if (value.tag === 'ok') {\n const encoded = item.encode(value.value);\n return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });\n }\n\n return ok({ tag: 'err', error: undefined });\n });\n}\n\nexport function result<T, EValue, TEncoded, EEncoded, EOk, EErr>(\n okEncoder: Encoder<T, TEncoded, EOk>,\n errEncoder: Encoder<EValue, EEncoded, EErr>,\n): Encoder<\n Result<T, EValue>,\n { readonly tag: 'ok'; readonly value: TEncoded } | {\n readonly error: EEncoded;\n readonly tag: 'err';\n },\n EOk | EErr\n> {\n return fromEncode<\n Result<T, EValue>,\n { readonly tag: 'ok'; readonly value: TEncoded } | {\n readonly error: EEncoded;\n readonly tag: 'err';\n },\n EOk | EErr\n >((value) => {\n if (value.tag === 'ok') {\n const encoded = okEncoder.encode(value.value);\n return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });\n }\n\n const encoded = errEncoder.encode(value.error);\n return isErr(encoded) ? encoded : ok({ tag: 'err', error: encoded.value });\n });\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Encoder<\n { readonly [K in keyof TShape]: EncoderInput<TShape[K]> },\n { readonly [K in keyof TShape]: EncoderOutput<TShape[K]> },\n EncoderError<TShape[keyof TShape]> | EncodeFailure\n> {\n return fromEncode<\n { readonly [K in keyof TShape]: EncoderInput<TShape[K]> },\n { readonly [K in keyof TShape]: EncoderOutput<TShape[K]> },\n EncoderError<TShape[keyof TShape]> | EncodeFailure\n >((value) => {\n if (!isPlainObject(value)) {\n return err<EncoderError<TShape[keyof TShape]> | EncodeFailure>(\n new EncodeFailure('Expected object.', value),\n );\n }\n\n const record = value as Record<string, unknown>;\n const encodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const encoder = shape[key];\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalEncoder(encoder)) {\n encodedObject[key] = undefined;\n continue;\n }\n\n return err<EncoderError<TShape[keyof TShape]> | EncodeFailure>(\n new EncodeFailure(`Missing field \"${key}\".`, value),\n );\n }\n\n const encoded = encoder.encode(rawValue as never) as Result<\n unknown,\n EncoderError<TShape[keyof TShape]> | EncodeFailure\n >;\n if (isErr(encoded)) {\n return encoded;\n }\n encodedObject[key] = encoded.value;\n }\n\n return ok(encodedObject as { readonly [K in keyof TShape]: EncoderOutput<TShape[K]> });\n });\n}\n\nfunction isOptionalEncoder(\n value: Encoder<unknown, unknown, unknown>,\n): value is OptionalEncoder<unknown, unknown, unknown> {\n return '__soundscriptOptional' in value && value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface ComponentContextKey<T> {
|
|
2
|
+
readonly __ss_component_context_key: symbol;
|
|
3
|
+
readonly __ss_component_context_type__?: (_value: T) => T;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface ComponentEvent<Detail = unknown, Target = unknown> {
|
|
7
|
+
readonly currentTarget: Target;
|
|
8
|
+
readonly detail: Detail;
|
|
9
|
+
readonly target: Target;
|
|
10
|
+
readonly type: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function state<T>(value: T): T;
|
|
14
|
+
export function awaited<T, PendingResult, FulfilledResult, RejectedResult = never>(
|
|
15
|
+
promise: PromiseLike<T>,
|
|
16
|
+
pending: PendingResult | (() => PendingResult),
|
|
17
|
+
fulfilled: (value: T) => FulfilledResult,
|
|
18
|
+
rejected?: (error: unknown) => RejectedResult,
|
|
19
|
+
): PendingResult | FulfilledResult | RejectedResult;
|
|
20
|
+
export function boundary<RenderResult, FallbackResult>(
|
|
21
|
+
render: () => RenderResult,
|
|
22
|
+
fallback: (error: unknown) => FallbackResult,
|
|
23
|
+
): RenderResult | FallbackResult;
|
|
24
|
+
export function context<T>(): ComponentContextKey<T>;
|
|
25
|
+
export function dispatch<T = undefined>(type: string, detail?: T): void;
|
|
26
|
+
export function derived<T>(compute: () => T): T;
|
|
27
|
+
export function effect<T>(callback: () => T): T;
|
|
28
|
+
export function onMount<T>(callback: () => T): T;
|
|
29
|
+
export function prop<T = never>(): T;
|
|
30
|
+
export function prop<T>(value: T): T;
|
|
31
|
+
export function provide<T, R>(context: ComponentContextKey<T>, value: T, content: R): R;
|
|
32
|
+
export function provide<T, R>(
|
|
33
|
+
context: ComponentContextKey<T>,
|
|
34
|
+
value: T,
|
|
35
|
+
content: () => R,
|
|
36
|
+
): R;
|
|
37
|
+
export function useContext<T>(value: ComponentContextKey<T>): T;
|
|
38
|
+
export function useStore<T>(value: T): T;
|
|
39
|
+
export function component<T>(value: T): T;
|
|
40
|
+
export function store<T>(value: T): T;
|