@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.
Files changed (73) hide show
  1. package/README.md +1 -1
  2. package/async.d.ts +3 -3
  3. package/async.js +2 -2
  4. package/async.js.map +1 -1
  5. package/codec.d.ts +3 -2
  6. package/codec.js +2 -2
  7. package/codec.js.map +1 -1
  8. package/compare.js +5 -10
  9. package/compare.js.map +1 -1
  10. package/decode.d.ts +6 -4
  11. package/decode.js +5 -5
  12. package/decode.js.map +1 -1
  13. package/derive.d.ts +6 -0
  14. package/derive.js +8 -0
  15. package/derive.js.map +1 -0
  16. package/encode.d.ts +11 -9
  17. package/encode.js +5 -5
  18. package/encode.js.map +1 -1
  19. package/experimental/thunk.js.map +1 -0
  20. package/fetch.d.ts +67 -0
  21. package/fetch.js +6 -0
  22. package/fetch.js.map +1 -0
  23. package/hash.js +9 -14
  24. package/hash.js.map +1 -1
  25. package/json.d.ts +29 -2
  26. package/json.js +124 -1
  27. package/json.js.map +1 -1
  28. package/numerics.d.ts +523 -0
  29. package/numerics.js +1357 -0
  30. package/numerics.js.map +1 -0
  31. package/package.json +122 -35
  32. package/random.d.ts +19 -0
  33. package/random.js +4 -0
  34. package/random.js.map +1 -0
  35. package/result.d.ts +21 -5
  36. package/result.js +55 -19
  37. package/result.js.map +1 -1
  38. package/soundscript/async.sts +7 -7
  39. package/soundscript/codec.sts +8 -7
  40. package/soundscript/compare.sts +5 -13
  41. package/soundscript/decode.sts +15 -13
  42. package/soundscript/derive.sts +7 -0
  43. package/soundscript/encode.sts +18 -16
  44. package/soundscript/fetch.sts +11 -0
  45. package/soundscript/hash.sts +9 -17
  46. package/soundscript/json.sts +209 -3
  47. package/soundscript/numerics.sts +1937 -0
  48. package/soundscript/random.sts +5 -0
  49. package/soundscript/result.sts +93 -24
  50. package/soundscript/text.sts +4 -0
  51. package/soundscript/typeclasses.sts +22 -16
  52. package/soundscript/url.sts +4 -0
  53. package/soundscript/value.sts +133 -0
  54. package/text.d.ts +24 -0
  55. package/text.js +4 -0
  56. package/text.js.map +1 -0
  57. package/typeclasses.d.ts +2 -2
  58. package/typeclasses.js +10 -9
  59. package/typeclasses.js.map +1 -1
  60. package/url.d.ts +37 -0
  61. package/url.js +4 -0
  62. package/url.js.map +1 -0
  63. package/value.d.ts +9 -0
  64. package/value.js +105 -0
  65. package/value.js.map +1 -0
  66. package/experimental/component.d.ts +0 -40
  67. package/experimental/component.js +0 -46
  68. package/experimental/component.js.map +0 -1
  69. package/soundscript/experimental/component.sts +0 -69
  70. package/thunk.js.map +0 -1
  71. /package/{thunk.d.ts → experimental/thunk.d.ts} +0 -0
  72. /package/{thunk.js → experimental/thunk.js} +0 -0
  73. /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 { tag: 'ok', value };
42
+ return new Ok(value);
4
43
  }
5
44
  export function err(error) {
6
- return { tag: 'err', error };
45
+ return new Err(error);
7
46
  }
8
47
  export function some(value) {
9
- return ok(value);
48
+ return new Some(value);
10
49
  }
11
50
  export function none() {
12
- return err();
51
+ return new None();
13
52
  }
14
53
  export function isOk(value) {
15
- return value.tag === 'ok';
54
+ return value instanceof Ok;
16
55
  }
17
56
  export function isErr(value) {
18
- return value.tag === 'err';
57
+ return value instanceof Err;
19
58
  }
20
59
  export function isSome(value) {
21
- return isOk(value);
60
+ return value instanceof Some;
22
61
  }
23
62
  export function isNone(value) {
24
- return isErr(value);
63
+ return value instanceof None;
25
64
  }
26
- function isPromiseLike(value) {
27
- return (typeof value === 'object' || typeof value === 'function') &&
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 (isPromiseLike(value)) {
36
- return Promise.resolve(value).then((resolved) => ok(resolved), (error) => {
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 isOk(value) ? ok(f(value.value)) : value;
85
+ return isSome(value) ? some(f(value.value)) : value;
50
86
  }
51
87
  function apOption(fn, value) {
52
- if (!isOk(fn)) {
88
+ if (!isSome(fn)) {
53
89
  return fn;
54
90
  }
55
- return isOk(value) ? ok(fn.value(value.value)) : value;
91
+ return isSome(value) ? some(fn.value(value.value)) : value;
56
92
  }
57
93
  function flatMapOption(value, f) {
58
- return isOk(value) ? f(value.value) : value;
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"]}
@@ -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 | PromiseLike<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 | PromiseLike<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 | PromiseLike<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: PromiseLike<A>): Task<A, E> {
280
- return fromPromise(() => Promise.resolve(promise)) as Task<A, E>;
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: PromiseLike<A>): Promise<A> {
313
- return Promise.resolve(promise);
312
+ fromPromise<A>(promise: Promise<A>): Promise<A> {
313
+ return promise;
314
314
  },
315
315
  };
@@ -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
- export interface Codec<T, TEncoded = unknown, DE = DecodeFailure, EE = EncodeFailure>
29
- extends Decoder<T, DE>, Encoder<T, TEncoded, EE> {}
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.tag === 'err' ? decoded : ok(decodeMap(decoded.value));
59
+ return isErr(decoded) ? decoded : ok(decodeMap(decoded.value));
59
60
  },
60
61
  },
61
62
  contramapEncoder(base, encodeMap),
@@ -1,4 +1,4 @@
1
- import type { Option, Result } from '@soundscript/soundscript/result';
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.tag !== right.tag) {
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 true;
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.tag !== right.tag) {
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.tag === 'err' && right.tag === 'err') {
110
+ if (isErr(left) && isErr(right)) {
119
111
  return errEq.equals(left.error, right.error);
120
112
  }
121
113
 
@@ -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
- export interface Decoder<T, E = DecodeFailure> {
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
- export interface OptionalDecoder<T, E = DecodeFailure> extends Decoder<T | undefined, E> {
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('ok'),
196
+ tag: literal('some'),
195
197
  value: item,
196
198
  }),
197
- (value) => ok(value.value) as Option<T>,
199
+ (value) => some(value.value) as Option<T>,
198
200
  ),
199
201
  map(
200
202
  object({
201
- tag: literal('err'),
203
+ tag: literal('none'),
202
204
  }),
203
- () => err() as Option<T>,
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;
@@ -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
- export interface Encoder<T, TEncoded = unknown, E = EncodeFailure> {
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
- export interface OptionalEncoder<T, TEncoded = T, E = EncodeFailure>
17
- extends Encoder<T | undefined, TEncoded | undefined, E> {
18
- readonly __soundscriptOptional: true;
19
- readonly inner: Encoder<T, TEncoded, E>;
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 error?: undefined; readonly tag: 'err' } | {
144
- readonly tag: 'ok';
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 error?: undefined; readonly tag: 'err' } | {
152
- readonly tag: 'ok';
153
+ { readonly tag: 'none' } | {
154
+ readonly tag: 'some';
153
155
  readonly value: TEncoded;
154
156
  },
155
157
  E
156
158
  >((value) => {
157
- if (value.tag === 'ok') {
159
+ if (isSome(value)) {
158
160
  const encoded = item.encode(value.value);
159
- return isErr(encoded) ? encoded : ok({ tag: 'ok', value: encoded.value });
161
+ return isErr(encoded) ? encoded : ok({ tag: 'some', value: encoded.value });
160
162
  }
161
163
 
162
- return ok({ tag: 'err', error: undefined });
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.tag === 'ok') {
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
  }
@@ -0,0 +1,11 @@
1
+ const fetchFn = fetch;
2
+ const HeadersCtor = Headers;
3
+ const RequestCtor = Request;
4
+ const ResponseCtor = Response;
5
+
6
+ export {
7
+ fetchFn as fetch,
8
+ HeadersCtor as Headers,
9
+ RequestCtor as Request,
10
+ ResponseCtor as Response,
11
+ };
@@ -1,5 +1,5 @@
1
1
  import type { Eq } from '@soundscript/soundscript/compare';
2
- import type { Option, Result } from '@soundscript/soundscript/result';
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.tag === 'ok'
101
- ? combineHashes(stringHash.hash('ok'), itemHash.hash(value.value))
102
- : stringHash.hash('err'),
100
+ isSome(value)
101
+ ? combineHashes(stringHash.hash('some'), itemHash.hash(value.value))
102
+ : stringHash.hash('none'),
103
103
  (left, right) => {
104
- if (left.tag !== right.tag) {
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 true;
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.tag === 'ok'
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.tag !== right.tag) {
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.tag === 'err' && right.tag === 'err') {
124
+ if (isErr(left) && isErr(right)) {
133
125
  return errHash.equals(left.error, right.error);
134
126
  }
135
127