@soundscript/soundscript 0.1.1 → 0.1.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/README.md +1 -1
- package/async.d.ts +3 -3
- package/async.js +2 -2
- package/async.js.map +1 -1
- package/codec.d.ts +3 -2
- package/codec.js +2 -2
- package/codec.js.map +1 -1
- package/compare.js +5 -10
- package/compare.js.map +1 -1
- package/decode.d.ts +6 -4
- package/decode.js +5 -5
- package/decode.js.map +1 -1
- package/derive.d.ts +6 -0
- package/derive.js +8 -0
- package/derive.js.map +1 -0
- package/encode.d.ts +11 -9
- package/encode.js +5 -5
- package/encode.js.map +1 -1
- package/experimental/thunk.js.map +1 -0
- package/fetch.d.ts +67 -0
- package/fetch.js +6 -0
- package/fetch.js.map +1 -0
- package/hash.js +9 -14
- package/hash.js.map +1 -1
- package/json.d.ts +29 -2
- package/json.js +124 -1
- package/json.js.map +1 -1
- package/numerics.d.ts +523 -0
- package/numerics.js +1357 -0
- package/numerics.js.map +1 -0
- package/package.json +122 -35
- package/random.d.ts +19 -0
- package/random.js +4 -0
- package/random.js.map +1 -0
- package/result.d.ts +21 -5
- package/result.js +55 -19
- package/result.js.map +1 -1
- package/soundscript/async.sts +7 -7
- package/soundscript/codec.sts +8 -7
- package/soundscript/compare.sts +5 -13
- package/soundscript/decode.sts +15 -13
- package/soundscript/derive.sts +7 -0
- package/soundscript/encode.sts +18 -16
- package/soundscript/fetch.sts +11 -0
- package/soundscript/hash.sts +9 -17
- package/soundscript/json.sts +209 -3
- package/soundscript/numerics.sts +1937 -0
- package/soundscript/random.sts +5 -0
- package/soundscript/result.sts +93 -24
- package/soundscript/text.sts +4 -0
- package/soundscript/typeclasses.sts +22 -16
- package/soundscript/url.sts +4 -0
- package/soundscript/value.sts +133 -0
- package/text.d.ts +24 -0
- package/text.js +4 -0
- package/text.js.map +1 -0
- package/typeclasses.d.ts +2 -2
- package/typeclasses.js +10 -9
- package/typeclasses.js.map +1 -1
- package/url.d.ts +37 -0
- package/url.js +4 -0
- package/url.js.map +1 -0
- package/value.d.ts +9 -0
- package/value.js +105 -0
- package/value.js.map +1 -0
- package/experimental/component.d.ts +0 -40
- package/experimental/component.js +0 -46
- package/experimental/component.js.map +0 -1
- package/soundscript/experimental/component.sts +0 -69
- package/thunk.js.map +0 -1
- /package/{thunk.d.ts → experimental/thunk.d.ts} +0 -0
- /package/{thunk.js → experimental/thunk.js} +0 -0
- /package/soundscript/{thunk.sts → experimental/thunk.sts} +0 -0
package/result.js
CHANGED
|
@@ -1,39 +1,75 @@
|
|
|
1
1
|
import { normalizeThrown } from '@soundscript/soundscript/failures';
|
|
2
|
+
import { __valueFactory, __valueKey, __valueReadonly, __valueShallowToken, } from '@soundscript/soundscript/value';
|
|
3
|
+
const makeOk = __valueFactory((value) => __valueKey('ok', __valueShallowToken(value)), () => Object.create(Ok.prototype), (instance, value) => {
|
|
4
|
+
__valueReadonly(instance, 'tag', 'ok');
|
|
5
|
+
__valueReadonly(instance, 'value', value);
|
|
6
|
+
});
|
|
7
|
+
const makeErr = __valueFactory((error) => __valueKey('err', __valueShallowToken(error)), () => Object.create(Err.prototype), (instance, error) => {
|
|
8
|
+
__valueReadonly(instance, 'tag', 'err');
|
|
9
|
+
__valueReadonly(instance, 'error', error);
|
|
10
|
+
});
|
|
11
|
+
const makeSome = __valueFactory((value) => __valueKey('some', __valueShallowToken(value)), () => Object.create(Some.prototype), (instance, value) => {
|
|
12
|
+
__valueReadonly(instance, 'tag', 'some');
|
|
13
|
+
__valueReadonly(instance, 'value', value);
|
|
14
|
+
});
|
|
15
|
+
const makeNone = __valueFactory(() => __valueKey('none'), () => Object.create(None.prototype), (instance) => {
|
|
16
|
+
__valueReadonly(instance, 'tag', 'none');
|
|
17
|
+
});
|
|
18
|
+
// #[variance(T: out)]
|
|
19
|
+
export class Ok {
|
|
20
|
+
constructor(value) {
|
|
21
|
+
return makeOk(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// #[variance(E: out)]
|
|
25
|
+
export class Err {
|
|
26
|
+
constructor(error) {
|
|
27
|
+
return makeErr(error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// #[variance(T: out)]
|
|
31
|
+
export class Some {
|
|
32
|
+
constructor(value) {
|
|
33
|
+
return makeSome(value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class None {
|
|
37
|
+
constructor() {
|
|
38
|
+
return makeNone();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
2
41
|
export function ok(value) {
|
|
3
|
-
return
|
|
42
|
+
return new Ok(value);
|
|
4
43
|
}
|
|
5
44
|
export function err(error) {
|
|
6
|
-
return
|
|
45
|
+
return new Err(error);
|
|
7
46
|
}
|
|
8
47
|
export function some(value) {
|
|
9
|
-
return
|
|
48
|
+
return new Some(value);
|
|
10
49
|
}
|
|
11
50
|
export function none() {
|
|
12
|
-
return
|
|
51
|
+
return new None();
|
|
13
52
|
}
|
|
14
53
|
export function isOk(value) {
|
|
15
|
-
return value
|
|
54
|
+
return value instanceof Ok;
|
|
16
55
|
}
|
|
17
56
|
export function isErr(value) {
|
|
18
|
-
return value
|
|
57
|
+
return value instanceof Err;
|
|
19
58
|
}
|
|
20
59
|
export function isSome(value) {
|
|
21
|
-
return
|
|
60
|
+
return value instanceof Some;
|
|
22
61
|
}
|
|
23
62
|
export function isNone(value) {
|
|
24
|
-
return
|
|
63
|
+
return value instanceof None;
|
|
25
64
|
}
|
|
26
|
-
function
|
|
27
|
-
return
|
|
28
|
-
value !== null &&
|
|
29
|
-
'then' in value &&
|
|
30
|
-
typeof value.then === 'function';
|
|
65
|
+
function isPromiseInstance(value) {
|
|
66
|
+
return value instanceof Promise;
|
|
31
67
|
}
|
|
32
68
|
export function resultOf(fn, mapError) {
|
|
33
69
|
try {
|
|
34
70
|
const value = fn();
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
71
|
+
if (isPromiseInstance(value)) {
|
|
72
|
+
return value.then((resolved) => ok(resolved), (error) => {
|
|
37
73
|
const normalized = normalizeThrown(error);
|
|
38
74
|
return err(mapError ? mapError(normalized) : normalized);
|
|
39
75
|
});
|
|
@@ -46,16 +82,16 @@ export function resultOf(fn, mapError) {
|
|
|
46
82
|
}
|
|
47
83
|
}
|
|
48
84
|
function mapOption(value, f) {
|
|
49
|
-
return
|
|
85
|
+
return isSome(value) ? some(f(value.value)) : value;
|
|
50
86
|
}
|
|
51
87
|
function apOption(fn, value) {
|
|
52
|
-
if (!
|
|
88
|
+
if (!isSome(fn)) {
|
|
53
89
|
return fn;
|
|
54
90
|
}
|
|
55
|
-
return
|
|
91
|
+
return isSome(value) ? some(fn.value(value.value)) : value;
|
|
56
92
|
}
|
|
57
93
|
function flatMapOption(value, f) {
|
|
58
|
-
return
|
|
94
|
+
return isSome(value) ? f(value.value) : value;
|
|
59
95
|
}
|
|
60
96
|
const optionMonadImpl = {
|
|
61
97
|
ap: apOption,
|
package/result.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"result.js","sourceRoot":"","sources":["./soundscript/result.sts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeThrown } from '@soundscript/soundscript/failures';\nimport { type Bind, type Kind, type Kind2, type TypeLambda } from '@soundscript/soundscript/hkt';\nimport { type Applicative, type Functor, type Monad } from '@soundscript/soundscript/typeclasses';\n\n// #[variance(T: out)]\nexport type Ok<T> = { readonly tag: 'ok'; readonly value: T };\n// #[variance(E: out)]\nexport type Err<E> = { readonly tag: 'err'; readonly error: E };\n\n// #[variance(T: out, E: out)]\nexport type Result<T, E> = Ok<T> | Err<E>;\n// #[variance(T: out)]\nexport type Some<T> = Ok<T>;\nexport type None = Err<void>;\n// #[variance(T: out)]\nexport type Option<T> = Result<T, void>;\n\nexport interface OptionF extends TypeLambda {\n readonly type: Option<this['Args'][0]>;\n}\n\nexport interface ResultF extends TypeLambda {\n readonly type: Result<this['Args'][1], this['Args'][0]>;\n}\n\nexport type OptionKind<T> = Kind<OptionF, T>;\nexport type ResultKind<E, T> = Kind2<ResultF, E, T>;\n\nexport function ok<T>(value: T): Result<T, never> {\n return { tag: 'ok', value };\n}\n\nexport function err(): Result<never, void>;\nexport function err<E>(error: E): Result<never, E>;\nexport function err<E>(error?: E): Result<never, E | void> {\n return { tag: 'err', error };\n}\n\nexport function some<T>(value: T): Option<T> {\n return ok(value);\n}\n\nexport function none(): Option<never> {\n return err();\n}\n\nexport function isOk<T, E>(value: Result<T, E>): value is Ok<T> {\n return value.tag === 'ok';\n}\n\nexport function isErr<T, E>(value: Result<T, E>): value is Err<E> {\n return value.tag === 'err';\n}\n\nexport function isSome<T>(value: Option<T>): value is Some<T> {\n return isOk(value);\n}\n\nexport function isNone<T>(value: Option<T>): value is None {\n return isErr(value);\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (typeof value === 'object' || typeof value === 'function') &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function';\n}\n\nexport function resultOf<T>(fn: () => Promise<T>): Promise<Result<T, Error>>;\nexport function resultOf<T, E>(\n fn: () => Promise<T>,\n mapError: (error: Error) => E,\n): Promise<Result<T, E>>;\nexport function resultOf<T>(fn: () => T): Result<T, Error>;\nexport function resultOf<T, E>(fn: () => T, mapError: (error: Error) => E): Result<T, E>;\nexport function resultOf<T, E>(\n fn: () => T | Promise<T>,\n mapError?: (error: Error) => E,\n): Result<T, E | Error> | Promise<Result<T, E | Error>> {\n try {\n const value = fn();\n if (isPromiseLike(value)) {\n return Promise.resolve(value as PromiseLike<T>).then(\n (resolved) => ok(resolved),\n (error) => {\n const normalized = normalizeThrown(error);\n return err(mapError ? mapError(normalized) : normalized);\n },\n );\n }\n return ok(value);\n } catch (error) {\n const normalized = normalizeThrown(error);\n return err(mapError ? mapError(normalized) : normalized);\n }\n}\n\nfunction mapOption<A, B>(value: Option<A>, f: (value: A) => B): Option<B> {\n return isOk(value) ? ok(f(value.value)) : value;\n}\n\nfunction apOption<A, B>(\n fn: Option<(value: A) => B>,\n value: Option<A>,\n): Option<B> {\n if (!isOk(fn)) {\n return fn;\n }\n return isOk(value) ? ok(fn.value(value.value)) : value;\n}\n\nfunction flatMapOption<A, B>(value: Option<A>, f: (value: A) => Option<B>): Option<B> {\n return isOk(value) ? f(value.value) : value;\n}\n\nconst optionMonadImpl: Monad<OptionF> = {\n ap: apOption,\n flatMap: flatMapOption,\n map: mapOption,\n pure: some,\n};\n\nexport const optionFunctor: Functor<OptionF> = optionMonadImpl;\nexport const optionApplicative: Applicative<OptionF> = optionMonadImpl;\nexport const optionMonad: Monad<OptionF> = optionMonadImpl;\n\nfunction mapResult<E, A, B>(value: Result<A, E>, f: (value: A) => B): Result<B, E> {\n return isOk(value) ? ok(f(value.value)) : value;\n}\n\nfunction apResult<E, A, B>(\n fn: Result<(value: A) => B, E>,\n value: Result<A, E>,\n): Result<B, E> {\n if (!isOk(fn)) {\n return fn;\n }\n return isOk(value) ? ok(fn.value(value.value)) : value;\n}\n\nfunction flatMapResult<E, A, B>(\n value: Result<A, E>,\n f: (value: A) => Result<B, E>,\n): Result<B, E> {\n return isOk(value) ? f(value.value) : value;\n}\n\nfunction createResultMonad<E>(): Monad<Bind<ResultF, [E]>> {\n return {\n ap: apResult,\n flatMap: flatMapResult,\n map: mapResult,\n pure: ok,\n };\n}\n\nexport function resultFunctor<E>(): Functor<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nexport function resultApplicative<E>(): Applicative<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nexport function resultMonad<E>(): Monad<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nfunction macroRuntimeError(name: string): never {\n throw new Error(\n `${name}(...) is a Soundscript macro and should be removed during Soundscript expansion.`,\n );\n}\n\nexport function Try<T, E>(value: Result<T, E>): T;\nexport function Try(_value: unknown): never {\n return macroRuntimeError('Try');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["./soundscript/result.sts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeThrown } from '@soundscript/soundscript/failures';\nimport { type Bind, type Kind, type Kind2, type TypeLambda } from '@soundscript/soundscript/hkt';\nimport { type Applicative, type Functor, type Monad } from '@soundscript/soundscript/typeclasses';\nimport {\n __valueFactory,\n __valueKey,\n __valueReadonly,\n __valueShallowToken,\n} from '@soundscript/soundscript/value';\n\nconst makeOk = __valueFactory<Ok<unknown>, [unknown]>(\n (value) => __valueKey('ok', __valueShallowToken(value)),\n () => Object.create(Ok.prototype) as Ok<unknown>,\n (instance, value) => {\n __valueReadonly(instance, 'tag', 'ok');\n __valueReadonly(instance, 'value', value);\n },\n);\n\nconst makeErr = __valueFactory<Err<unknown>, [unknown]>(\n (error) => __valueKey('err', __valueShallowToken(error)),\n () => Object.create(Err.prototype) as Err<unknown>,\n (instance, error) => {\n __valueReadonly(instance, 'tag', 'err');\n __valueReadonly(instance, 'error', error);\n },\n);\n\nconst makeSome = __valueFactory<Some<unknown>, [unknown]>(\n (value) => __valueKey('some', __valueShallowToken(value)),\n () => Object.create(Some.prototype) as Some<unknown>,\n (instance, value) => {\n __valueReadonly(instance, 'tag', 'some');\n __valueReadonly(instance, 'value', value);\n },\n);\n\nconst makeNone = __valueFactory<None, []>(\n () => __valueKey('none'),\n () => Object.create(None.prototype) as None,\n (instance) => {\n __valueReadonly(instance, 'tag', 'none');\n },\n);\n\n// #[variance(T: out)]\nexport class Ok<T> {\n readonly tag!: 'ok';\n readonly value!: T;\n\n constructor(value: T) {\n return makeOk(value) as Ok<T>;\n }\n}\n\n// #[variance(E: out)]\nexport class Err<E> {\n readonly tag!: 'err';\n readonly error!: E;\n\n constructor(error: E) {\n return makeErr(error) as Err<E>;\n }\n}\n\n// #[variance(T: out, E: out)]\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n// #[variance(T: out)]\nexport class Some<T> {\n readonly tag!: 'some';\n readonly value!: T;\n\n constructor(value: T) {\n return makeSome(value) as Some<T>;\n }\n}\n\nexport class None {\n readonly tag!: 'none';\n\n constructor() {\n return makeNone();\n }\n}\n\n// #[variance(T: out)]\nexport type Option<T> = Some<T> | None;\n\nexport interface OptionF extends TypeLambda {\n readonly type: Option<this['Args'][0]>;\n}\n\nexport interface ResultF extends TypeLambda {\n readonly type: Result<this['Args'][1], this['Args'][0]>;\n}\n\nexport type OptionKind<T> = Kind<OptionF, T>;\nexport type ResultKind<E, T> = Kind2<ResultF, E, T>;\n\nexport function ok<T>(value: T): Result<T, never> {\n return new Ok(value);\n}\n\nexport function err(): Result<never, void>;\nexport function err<E>(error: E): Result<never, E>;\nexport function err<E>(error?: E): Result<never, E | void> {\n return new Err(error);\n}\n\nexport function some<T>(value: T): Option<T> {\n return new Some(value);\n}\n\nexport function none(): Option<never> {\n return new None();\n}\n\nexport function isOk<T, E>(value: Result<T, E>): value is Ok<T> {\n return value instanceof Ok;\n}\n\nexport function isErr<T, E>(value: Result<T, E>): value is Err<E> {\n return value instanceof Err;\n}\n\nexport function isSome<T>(value: Option<T>): value is Some<T> {\n return value instanceof Some;\n}\n\nexport function isNone<T>(value: Option<T>): value is None {\n return value instanceof None;\n}\n\nfunction isPromiseInstance<T>(value: unknown): value is Promise<T> {\n return value instanceof Promise;\n}\n\nexport function resultOf<T>(fn: () => Promise<T>): Promise<Result<T, Error>>;\nexport function resultOf<T, E>(\n fn: () => Promise<T>,\n mapError: (error: Error) => E,\n): Promise<Result<T, E>>;\nexport function resultOf<T>(fn: () => T): Result<T, Error>;\nexport function resultOf<T, E>(fn: () => T, mapError: (error: Error) => E): Result<T, E>;\nexport function resultOf<T, E>(\n fn: () => T | Promise<T>,\n mapError?: (error: Error) => E,\n): Result<T, E | Error> | Promise<Result<T, E | Error>> {\n try {\n const value = fn();\n if (isPromiseInstance<T>(value)) {\n return value.then(\n (resolved) => ok(resolved),\n (error) => {\n const normalized = normalizeThrown(error);\n return err(mapError ? mapError(normalized) : normalized);\n },\n );\n }\n return ok(value);\n } catch (error) {\n const normalized = normalizeThrown(error);\n return err(mapError ? mapError(normalized) : normalized);\n }\n}\n\nfunction mapOption<A, B>(value: Option<A>, f: (value: A) => B): Option<B> {\n return isSome(value) ? some(f(value.value)) : value;\n}\n\nfunction apOption<A, B>(\n fn: Option<(value: A) => B>,\n value: Option<A>,\n): Option<B> {\n if (!isSome(fn)) {\n return fn;\n }\n return isSome(value) ? some(fn.value(value.value)) : value;\n}\n\nfunction flatMapOption<A, B>(value: Option<A>, f: (value: A) => Option<B>): Option<B> {\n return isSome(value) ? f(value.value) : value;\n}\n\nconst optionMonadImpl: Monad<OptionF> = {\n ap: apOption,\n flatMap: flatMapOption,\n map: mapOption,\n pure: some,\n};\n\nexport const optionFunctor: Functor<OptionF> = optionMonadImpl;\nexport const optionApplicative: Applicative<OptionF> = optionMonadImpl;\nexport const optionMonad: Monad<OptionF> = optionMonadImpl;\n\nfunction mapResult<E, A, B>(value: Result<A, E>, f: (value: A) => B): Result<B, E> {\n return isOk(value) ? ok(f(value.value)) : value;\n}\n\nfunction apResult<E, A, B>(\n fn: Result<(value: A) => B, E>,\n value: Result<A, E>,\n): Result<B, E> {\n if (!isOk(fn)) {\n return fn;\n }\n return isOk(value) ? ok(fn.value(value.value)) : value;\n}\n\nfunction flatMapResult<E, A, B>(\n value: Result<A, E>,\n f: (value: A) => Result<B, E>,\n): Result<B, E> {\n return isOk(value) ? f(value.value) : value;\n}\n\nfunction createResultMonad<E>(): Monad<Bind<ResultF, [E]>> {\n return {\n ap: apResult,\n flatMap: flatMapResult,\n map: mapResult,\n pure: ok,\n };\n}\n\nexport function resultFunctor<E>(): Functor<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nexport function resultApplicative<E>(): Applicative<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nexport function resultMonad<E>(): Monad<Bind<ResultF, [E]>> {\n return createResultMonad<E>();\n}\n\nfunction macroRuntimeError(name: string): never {\n throw new Error(\n `${name}(...) is a Soundscript macro and should be removed during Soundscript expansion.`,\n );\n}\n\nexport function Try<T, E>(value: Result<T, E>): T;\nexport function Try(_value: unknown): never {\n return macroRuntimeError('Try');\n}\n"]}
|
package/soundscript/async.sts
CHANGED
|
@@ -109,7 +109,7 @@ export function flatMap<A, B, E1, E2>(
|
|
|
109
109
|
|
|
110
110
|
export function recover<A, B, E>(
|
|
111
111
|
task: Task<A, E>,
|
|
112
|
-
project: (error: E) => B |
|
|
112
|
+
project: (error: E) => B | Promise<B>,
|
|
113
113
|
): Task<A | B, Error> {
|
|
114
114
|
return async (signal?: AbortSignalLike) => {
|
|
115
115
|
const result = await task(signal);
|
|
@@ -123,7 +123,7 @@ export function recover<A, B, E>(
|
|
|
123
123
|
|
|
124
124
|
export function tap<A, E>(
|
|
125
125
|
task: Task<A, E>,
|
|
126
|
-
effect: (value: A) => unknown |
|
|
126
|
+
effect: (value: A) => unknown | Promise<unknown>,
|
|
127
127
|
): Task<A, E | Error> {
|
|
128
128
|
return async (signal?: AbortSignalLike) => {
|
|
129
129
|
const result = await task(signal);
|
|
@@ -138,7 +138,7 @@ export function tap<A, E>(
|
|
|
138
138
|
|
|
139
139
|
export function tapError<A, E>(
|
|
140
140
|
task: Task<A, E>,
|
|
141
|
-
effect: (error: E) => unknown |
|
|
141
|
+
effect: (error: E) => unknown | Promise<unknown>,
|
|
142
142
|
): Task<A, E | Error> {
|
|
143
143
|
return async (signal?: AbortSignalLike) => {
|
|
144
144
|
const result = await task(signal);
|
|
@@ -276,8 +276,8 @@ export function taskAsyncMonad<E>(): AsyncMonad<Bind<TaskF, [E]>> {
|
|
|
276
276
|
const monad = createTaskMonad<E>();
|
|
277
277
|
return {
|
|
278
278
|
...monad,
|
|
279
|
-
fromPromise<A>(promise:
|
|
280
|
-
return fromPromise(() =>
|
|
279
|
+
fromPromise<A>(promise: Promise<A>): Task<A, E> {
|
|
280
|
+
return fromPromise(() => promise) as Task<A, E>;
|
|
281
281
|
},
|
|
282
282
|
};
|
|
283
283
|
}
|
|
@@ -309,7 +309,7 @@ export const promiseMonad: Monad<PromiseF> = {
|
|
|
309
309
|
|
|
310
310
|
export const promiseAsyncMonad: AsyncMonad<PromiseF> = {
|
|
311
311
|
...promiseMonad,
|
|
312
|
-
fromPromise<A>(promise:
|
|
313
|
-
return
|
|
312
|
+
fromPromise<A>(promise: Promise<A>): Promise<A> {
|
|
313
|
+
return promise;
|
|
314
314
|
},
|
|
315
315
|
};
|
package/soundscript/codec.sts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
stringEncoder as stringEncoderValue,
|
|
16
16
|
} from '@soundscript/soundscript/encode';
|
|
17
17
|
import type { Invariant } from '@soundscript/soundscript/typeclasses';
|
|
18
|
-
import { ok } from '@soundscript/soundscript/result';
|
|
18
|
+
import { isErr, ok, type Result } from '@soundscript/soundscript/result';
|
|
19
19
|
|
|
20
20
|
export type { EncodeFailure, Encoder } from '@soundscript/soundscript/encode';
|
|
21
21
|
export {
|
|
@@ -25,8 +25,9 @@ export {
|
|
|
25
25
|
stringEncoderValue as stringEncoder,
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// #[variance(T: inout, TEncoded: out, DE: out, EE: out)]
|
|
29
|
+
export type Codec<T, TEncoded = unknown, DE = DecodeFailure, EE = EncodeFailure> =
|
|
30
|
+
Decoder<T, DE> & Encoder<T, TEncoded, EE>;
|
|
30
31
|
|
|
31
32
|
export interface CodecF extends TypeLambda {
|
|
32
33
|
readonly type: Codec<this['Args'][3], this['Args'][2], this['Args'][1], this['Args'][0]>;
|
|
@@ -37,10 +38,10 @@ export function codec<T, TEncoded, DE, EE>(
|
|
|
37
38
|
encoder: Encoder<T, TEncoded, EE>,
|
|
38
39
|
): Codec<T, TEncoded, DE, EE> {
|
|
39
40
|
return {
|
|
40
|
-
decode(value) {
|
|
41
|
+
decode(value): Result<T, DE> {
|
|
41
42
|
return decoder.decode(value);
|
|
42
43
|
},
|
|
43
|
-
encode(value) {
|
|
44
|
+
encode(value): Result<TEncoded, EE> {
|
|
44
45
|
return encoder.encode(value);
|
|
45
46
|
},
|
|
46
47
|
};
|
|
@@ -53,9 +54,9 @@ export function imap<A, B, TEncoded, DE, EE>(
|
|
|
53
54
|
): Codec<B, TEncoded, DE, EE> {
|
|
54
55
|
return codec(
|
|
55
56
|
{
|
|
56
|
-
decode(value) {
|
|
57
|
+
decode(value): Result<B, DE> {
|
|
57
58
|
const decoded = base.decode(value);
|
|
58
|
-
return decoded
|
|
59
|
+
return isErr(decoded) ? decoded : ok(decodeMap(decoded.value));
|
|
59
60
|
},
|
|
60
61
|
},
|
|
61
62
|
contramapEncoder(base, encodeMap),
|
package/soundscript/compare.sts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { isErr, isNone, isOk, isSome, type Option, type Result } from '@soundscript/soundscript/result';
|
|
2
2
|
|
|
3
3
|
export type Ordering = -1 | 0 | 1;
|
|
4
4
|
|
|
@@ -91,15 +91,11 @@ export function tupleEq<const TEqs extends readonly Eq<unknown>[]>(
|
|
|
91
91
|
export function optionEq<T>(itemEq: Eq<T>): Eq<Option<T>> {
|
|
92
92
|
return {
|
|
93
93
|
equals(left, right) {
|
|
94
|
-
if (left
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (left.tag === 'ok' && right.tag === 'ok') {
|
|
94
|
+
if (isSome(left) && isSome(right)) {
|
|
99
95
|
return itemEq.equals(left.value, right.value);
|
|
100
96
|
}
|
|
101
97
|
|
|
102
|
-
return
|
|
98
|
+
return isNone(left) && isNone(right);
|
|
103
99
|
},
|
|
104
100
|
};
|
|
105
101
|
}
|
|
@@ -107,15 +103,11 @@ export function optionEq<T>(itemEq: Eq<T>): Eq<Option<T>> {
|
|
|
107
103
|
export function resultEq<T, E>(okEq: Eq<T>, errEq: Eq<E>): Eq<Result<T, E>> {
|
|
108
104
|
return {
|
|
109
105
|
equals(left, right) {
|
|
110
|
-
if (left
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (left.tag === 'ok' && right.tag === 'ok') {
|
|
106
|
+
if (isOk(left) && isOk(right)) {
|
|
115
107
|
return okEq.equals(left.value, right.value);
|
|
116
108
|
}
|
|
117
109
|
|
|
118
|
-
if (left
|
|
110
|
+
if (isErr(left) && isErr(right)) {
|
|
119
111
|
return errEq.equals(left.error, right.error);
|
|
120
112
|
}
|
|
121
113
|
|
package/soundscript/decode.sts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';
|
|
2
|
-
import { err, isErr, ok, type Option, type Result } from '@soundscript/soundscript/result';
|
|
2
|
+
import { err, isErr, none, ok, some, type Option, type Result } from '@soundscript/soundscript/result';
|
|
3
3
|
|
|
4
4
|
export type DecodePathSegment = string | number;
|
|
5
5
|
export type DecodePath = readonly DecodePathSegment[];
|
|
@@ -33,14 +33,16 @@ export class DecodeFailure extends Failure {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
// #[variance(T: out, E: out)]
|
|
37
|
+
export type Decoder<T, E = DecodeFailure> = {
|
|
37
38
|
decode(value: unknown): Result<T, E>;
|
|
38
|
-
}
|
|
39
|
+
};
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
// #[variance(T: out, E: out)]
|
|
42
|
+
export type OptionalDecoder<T, E = DecodeFailure> = Decoder<T | undefined, E> & {
|
|
41
43
|
readonly __soundscriptOptional: true;
|
|
42
44
|
readonly inner: Decoder<T, E>;
|
|
43
|
-
}
|
|
45
|
+
};
|
|
44
46
|
|
|
45
47
|
type DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;
|
|
46
48
|
type DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;
|
|
@@ -49,7 +51,7 @@ type ObjectShape = Record<string, Decoder<unknown, unknown>>;
|
|
|
49
51
|
type TupleShape = readonly Decoder<unknown, unknown>[];
|
|
50
52
|
|
|
51
53
|
export const string: Decoder<string> = {
|
|
52
|
-
decode(value) {
|
|
54
|
+
decode(value): Result<string, DecodeFailure> {
|
|
53
55
|
return typeof value === 'string'
|
|
54
56
|
? ok(value)
|
|
55
57
|
: err(new DecodeFailure('Expected string.', { cause: value }));
|
|
@@ -57,7 +59,7 @@ export const string: Decoder<string> = {
|
|
|
57
59
|
};
|
|
58
60
|
|
|
59
61
|
export const number: Decoder<number> = {
|
|
60
|
-
decode(value) {
|
|
62
|
+
decode(value): Result<number, DecodeFailure> {
|
|
61
63
|
return typeof value === 'number'
|
|
62
64
|
? ok(value)
|
|
63
65
|
: err(new DecodeFailure('Expected number.', { cause: value }));
|
|
@@ -65,7 +67,7 @@ export const number: Decoder<number> = {
|
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
export const boolean: Decoder<boolean> = {
|
|
68
|
-
decode(value) {
|
|
70
|
+
decode(value): Result<boolean, DecodeFailure> {
|
|
69
71
|
return typeof value === 'boolean'
|
|
70
72
|
? ok(value)
|
|
71
73
|
: err(new DecodeFailure('Expected boolean.', { cause: value }));
|
|
@@ -73,7 +75,7 @@ export const boolean: Decoder<boolean> = {
|
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
export const bigint: Decoder<bigint> = {
|
|
76
|
-
decode(value) {
|
|
78
|
+
decode(value): Result<bigint, DecodeFailure> {
|
|
77
79
|
if (typeof value === 'bigint') {
|
|
78
80
|
return ok(value);
|
|
79
81
|
}
|
|
@@ -191,16 +193,16 @@ export function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | Decode
|
|
|
191
193
|
return union(
|
|
192
194
|
map(
|
|
193
195
|
object({
|
|
194
|
-
tag: literal('
|
|
196
|
+
tag: literal('some'),
|
|
195
197
|
value: item,
|
|
196
198
|
}),
|
|
197
|
-
(value) =>
|
|
199
|
+
(value) => some(value.value) as Option<T>,
|
|
198
200
|
),
|
|
199
201
|
map(
|
|
200
202
|
object({
|
|
201
|
-
tag: literal('
|
|
203
|
+
tag: literal('none'),
|
|
202
204
|
}),
|
|
203
|
-
() =>
|
|
205
|
+
() => none() as Option<T>,
|
|
204
206
|
),
|
|
205
207
|
);
|
|
206
208
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Macro binding placeholders. The compiler-owned macro pipeline consumes these symbols.
|
|
2
|
+
export const eq: unknown = undefined;
|
|
3
|
+
export const hash: unknown = undefined;
|
|
4
|
+
export const decode: unknown = undefined;
|
|
5
|
+
export const encode: unknown = undefined;
|
|
6
|
+
export const codec: unknown = undefined;
|
|
7
|
+
export const tagged: unknown = undefined;
|
package/soundscript/encode.sts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Bind, type Kind3, type TypeLambda } from '@soundscript/soundscript/hkt';
|
|
2
2
|
import { Failure } from '@soundscript/soundscript/failures';
|
|
3
|
-
import { err, isErr, ok, type Option, type Result } from '@soundscript/soundscript/result';
|
|
3
|
+
import { err, isErr, isOk, isSome, ok, type Option, type Result } from '@soundscript/soundscript/result';
|
|
4
4
|
import type { Contravariant } from '@soundscript/soundscript/typeclasses';
|
|
5
5
|
|
|
6
6
|
export class EncodeFailure extends Failure {
|
|
@@ -9,15 +9,17 @@ export class EncodeFailure extends Failure {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// #[variance(T: in, TEncoded: out, E: out)]
|
|
13
|
+
export type Encoder<T, TEncoded = unknown, E = EncodeFailure> = {
|
|
13
14
|
encode(value: T): Result<TEncoded, E>;
|
|
14
|
-
}
|
|
15
|
+
};
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// #[variance(T: in, TEncoded: out, E: out)]
|
|
18
|
+
export type OptionalEncoder<T, TEncoded = T, E = EncodeFailure> =
|
|
19
|
+
Encoder<T | undefined, TEncoded | undefined, E> & {
|
|
20
|
+
readonly __soundscriptOptional: true;
|
|
21
|
+
readonly inner: Encoder<T, TEncoded, E>;
|
|
22
|
+
};
|
|
21
23
|
|
|
22
24
|
type EncoderInput<TEncoder> = TEncoder extends Encoder<infer T, unknown, unknown> ? T : never;
|
|
23
25
|
type EncoderOutput<TEncoder> = TEncoder extends Encoder<unknown, infer TEncoded, unknown> ? TEncoded
|
|
@@ -140,26 +142,26 @@ export function option<T, TEncoded, E>(
|
|
|
140
142
|
item: Encoder<T, TEncoded, E>,
|
|
141
143
|
): Encoder<
|
|
142
144
|
Option<T>,
|
|
143
|
-
{ readonly
|
|
144
|
-
readonly tag: '
|
|
145
|
+
{ readonly tag: 'none' } | {
|
|
146
|
+
readonly tag: 'some';
|
|
145
147
|
readonly value: TEncoded;
|
|
146
148
|
},
|
|
147
149
|
E
|
|
148
150
|
> {
|
|
149
151
|
return fromEncode<
|
|
150
152
|
Option<T>,
|
|
151
|
-
{ readonly
|
|
152
|
-
readonly tag: '
|
|
153
|
+
{ readonly tag: 'none' } | {
|
|
154
|
+
readonly tag: 'some';
|
|
153
155
|
readonly value: TEncoded;
|
|
154
156
|
},
|
|
155
157
|
E
|
|
156
158
|
>((value) => {
|
|
157
|
-
if (value
|
|
159
|
+
if (isSome(value)) {
|
|
158
160
|
const encoded = item.encode(value.value);
|
|
159
|
-
return isErr(encoded) ? encoded : ok({ tag: '
|
|
161
|
+
return isErr(encoded) ? encoded : ok({ tag: 'some', value: encoded.value });
|
|
160
162
|
}
|
|
161
163
|
|
|
162
|
-
return ok({ tag: '
|
|
164
|
+
return ok({ tag: 'none' });
|
|
163
165
|
});
|
|
164
166
|
}
|
|
165
167
|
|
|
@@ -182,7 +184,7 @@ export function result<T, EValue, TEncoded, EEncoded, EOk, EErr>(
|
|
|
182
184
|
},
|
|
183
185
|
EOk | EErr
|
|
184
186
|
>((value) => {
|
|
185
|
-
if (value
|
|
187
|
+
if (isOk(value)) {
|
|
186
188
|
const encoded = okEncoder.encode(value.value);
|
|
187
189
|
return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });
|
|
188
190
|
}
|
package/soundscript/hash.sts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Eq } from '@soundscript/soundscript/compare';
|
|
2
|
-
import type
|
|
2
|
+
import { isErr, isNone, isOk, isSome, type Option, type Result } from '@soundscript/soundscript/result';
|
|
3
3
|
|
|
4
4
|
export type HashCode = number;
|
|
5
5
|
|
|
@@ -97,19 +97,15 @@ export function tupleHash<const THashEqs extends readonly HashEq<unknown>[]>(
|
|
|
97
97
|
export function optionHash<T>(itemHash: HashEq<T>): HashEq<Option<T>> {
|
|
98
98
|
return fromHashEq(
|
|
99
99
|
(value) =>
|
|
100
|
-
value
|
|
101
|
-
? combineHashes(stringHash.hash('
|
|
102
|
-
: stringHash.hash('
|
|
100
|
+
isSome(value)
|
|
101
|
+
? combineHashes(stringHash.hash('some'), itemHash.hash(value.value))
|
|
102
|
+
: stringHash.hash('none'),
|
|
103
103
|
(left, right) => {
|
|
104
|
-
if (left
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (left.tag === 'ok' && right.tag === 'ok') {
|
|
104
|
+
if (isSome(left) && isSome(right)) {
|
|
109
105
|
return itemHash.equals(left.value, right.value);
|
|
110
106
|
}
|
|
111
107
|
|
|
112
|
-
return
|
|
108
|
+
return isNone(left) && isNone(right);
|
|
113
109
|
},
|
|
114
110
|
);
|
|
115
111
|
}
|
|
@@ -117,19 +113,15 @@ export function optionHash<T>(itemHash: HashEq<T>): HashEq<Option<T>> {
|
|
|
117
113
|
export function resultHash<T, E>(okHash: HashEq<T>, errHash: HashEq<E>): HashEq<Result<T, E>> {
|
|
118
114
|
return fromHashEq(
|
|
119
115
|
(value) =>
|
|
120
|
-
value
|
|
116
|
+
isOk(value)
|
|
121
117
|
? combineHashes(stringHash.hash('ok'), okHash.hash(value.value))
|
|
122
118
|
: combineHashes(stringHash.hash('err'), errHash.hash(value.error)),
|
|
123
119
|
(left, right) => {
|
|
124
|
-
if (left
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (left.tag === 'ok' && right.tag === 'ok') {
|
|
120
|
+
if (isOk(left) && isOk(right)) {
|
|
129
121
|
return okHash.equals(left.value, right.value);
|
|
130
122
|
}
|
|
131
123
|
|
|
132
|
-
if (left
|
|
124
|
+
if (isErr(left) && isErr(right)) {
|
|
133
125
|
return errHash.equals(left.error, right.error);
|
|
134
126
|
}
|
|
135
127
|
|