functionalscript 0.12.1 → 0.12.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.
@@ -6,20 +6,20 @@ declare const _default: {
6
6
  testSort?: never;
7
7
  testIdentity?: never;
8
8
  } | {
9
- testSort: () => void;
10
- testIdentity: () => void;
11
9
  testPrimitives?: never;
12
10
  testArray?: never;
13
11
  testObj?: never;
12
+ testSort: () => void;
13
+ testIdentity: () => void;
14
14
  })[];
15
15
  stringifyAsTree: ({
16
16
  sort: () => void;
17
17
  identity: () => void;
18
18
  stringify?: never;
19
19
  } | {
20
- stringify: () => void;
21
20
  sort?: never;
22
21
  identity?: never;
22
+ stringify: () => void;
23
23
  })[];
24
24
  };
25
25
  export default _default;
@@ -1,4 +1,5 @@
1
1
  import { type List } from '../types/list/module.f.ts';
2
+ import { type Vec } from '../types/bit_vec/module.f.ts';
2
3
  type Tag = string;
3
4
  type Element1 = readonly [Tag, ...Node[]];
4
5
  type Element2 = readonly [Tag, Attributes, ...Node[]];
@@ -28,4 +29,5 @@ export declare const html: (_: Element) => List<string>;
28
29
  * Renders an HTML element tree to a final string.
29
30
  */
30
31
  export declare const htmlToString: (_: Element) => string;
32
+ export declare const htmlUtf8: (...head: readonly Node[]) => (...body: readonly Node[]) => Vec;
31
33
  export {};
package/html/module.f.js CHANGED
@@ -3,6 +3,8 @@ import { concat, concat as stringConcat } from "../types/string/module.f.js";
3
3
  import { compose } from "../types/function/module.f.js";
4
4
  import { stringToList } from "../text/utf16/module.f.js";
5
5
  import { includes } from "../types/array/module.f.js";
6
+ import {} from "../types/bit_vec/module.f.js";
7
+ import { utf8 } from "../text/module.f.js";
6
8
  const { fromCharCode } = String;
7
9
  const { entries } = Object;
8
10
  /**
@@ -87,3 +89,5 @@ export const html = compose(element)(listConcat(['<!DOCTYPE html>']));
87
89
  * Renders an HTML element tree to a final string.
88
90
  */
89
91
  export const htmlToString = compose(html)(stringConcat);
92
+ const metaUtf8 = ['meta', { charset: 'UTF-8' }];
93
+ export const htmlUtf8 = (...head) => (...body) => utf8(htmlToString(['html', ['head', metaUtf8, ...head], ['body', ...body]]));
package/json/module.f.js CHANGED
@@ -60,7 +60,3 @@ export const serialize = sort => {
60
60
  */
61
61
  export const stringify = sort => compose(serialize(sort))(concat);
62
62
  export const parse = JSON.parse;
63
- /*
64
- export const isObject = (value: Unknown): value is Object =>
65
- typeof value === 'object' && value !== null && !(value instanceof Array)
66
- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.js",
@@ -17,17 +17,8 @@ export declare const tag0List: readonly ["bigint", "boolean", "number", "string"
17
17
  export type Tag0 = typeof tag0List[number];
18
18
  /** Info tuple for a nullary tag: `readonly[tag]`. */
19
19
  export type Info0<T extends Tag0> = T extends Tag0 ? readonly [T] : never;
20
- /**
21
- * The descriptor returned by a `Thunk`. One of:
22
- * - `['const', Const]` — a constant/literal schema (used in recursive thunks)
23
- * - `Info0<Tag0>` — a nullary primitive tag
24
- * - `Info1<Tag1, Type>` — a unary parametric tag with an inner type
25
- */
26
- export type Info = readonly ['const', Const] | Info0<Tag0> | Info1<Tag1, Type>;
27
- /** A lazy schema: a zero-argument function returning an `Info` descriptor. */
28
- export type Thunk = () => Info;
29
20
  /** Any schema: a `Const` used directly, or a `Thunk` for tag-based/recursive schemas. */
30
- export type Type = (() => (readonly ['const', Const] | readonly ['bigint'] | readonly ['boolean'] | readonly ['number'] | readonly ['string'] | readonly ['unknown'] | readonly ['array', Type] | readonly ['record', Type])) | Const;
21
+ export type Type = (() => (readonly ['const', Const] | readonly ['bigint'] | readonly ['boolean'] | readonly ['number'] | readonly ['string'] | readonly ['unknown'] | readonly ['array', Type] | readonly ['record', Type] | readonly ['or', ...readonly Type[]])) | Const;
31
22
  /** The type of a nullary thunk for `Tag0`. */
32
23
  type Type0<T extends Tag0> = () => Info0<T>;
33
24
  /** Schema type for `boolean`. */
@@ -67,4 +58,8 @@ export declare const array: MakeType1<'array'>;
67
58
  export type Record<T extends Type> = Type1<'record', T>;
68
59
  /** Constructs a schema that validates `{ readonly[K in string]: Ts<T> }`. */
69
60
  export declare const record: MakeType1<'record'>;
61
+ /** Schema type for a union of types `T`. */
62
+ export type Or<T extends readonly Type[]> = () => readonly ['or', ...T];
63
+ /** Constructs a schema that validates a value matching any of the given schemas. */
64
+ export declare const or: <T extends readonly Type[]>(...types: T) => Or<T>;
70
65
  export {};
@@ -19,3 +19,5 @@ const type1 = (key) => t => () => [key, t];
19
19
  export const array = type1('array');
20
20
  /** Constructs a schema that validates `{ readonly[K in string]: Ts<T> }`. */
21
21
  export const record = type1('record');
22
+ /** Constructs a schema that validates a value matching any of the given schemas. */
23
+ export const or = (...types) => () => ['or', ...types];
@@ -1,5 +1,5 @@
1
1
  import type { Unknown as DjsUnknown } from '../../../djs/module.f.ts';
2
- import type { Tag0, Tag1, Const, Struct, Tuple, Info0, Info1, Info, Type } from '../module.f.ts';
2
+ import type { Tag0, Tag1, Struct, Tuple, Type } from '../module.f.ts';
3
3
  import type { ReadonlyRecord } from '../../object/module.f.ts';
4
4
  /** Maps a `Tag0` to its TypeScript type. */
5
5
  export type Info0Ts<T extends Tag0> = T extends 'boolean' ? boolean : T extends 'number' ? number : T extends 'string' ? string : T extends 'bigint' ? bigint : T extends 'unknown' ? DjsUnknown : never;
@@ -11,8 +11,6 @@ export type ConstTs<T> = T extends readonly Type[] ? TupleTs<T> : T extends {
11
11
  } : T;
12
12
  /** Maps a `Tag1` and inner type to its TypeScript type. */
13
13
  export type Info1Ts<K extends Tag1, T extends Type> = K extends 'array' ? ArrayTs<T> : K extends 'record' ? RecordTs<T> : never;
14
- /** Maps an `Info` descriptor to its TypeScript type. */
15
- export type InfoTs<T extends Info> = T extends readonly ['const', infer C extends Const] ? ConstTs<C> : T extends Info0<infer K extends Tag0> ? Info0Ts<K> : T extends Info1<infer K extends Tag1, infer I extends Type> ? Info1Ts<K, I> : never;
16
14
  /** Maps an array schema `T` to `readonly Ts<T>[]`. */
17
15
  export type ArrayTs<T extends Type> = ReadonlyArray<Ts<T>>;
18
16
  /** Maps a record schema `T` to `{ readonly[K in string]: Ts<T> }`. */
@@ -41,4 +39,4 @@ export type StructTs<T extends Struct> = {
41
39
  */
42
40
  export type Ts<T extends Type> = T extends () => infer I ? (I extends readonly ['const', infer C] ? ConstTs<C> : I extends readonly ['boolean'] ? boolean : I extends readonly ['number'] ? number : I extends readonly ['string'] ? string : I extends readonly ['bigint'] ? bigint : I extends readonly ['unknown'] ? DjsUnknown : I extends readonly ['array', infer E extends Type] ? readonly Ts<E>[] : I extends readonly ['record', infer E extends Type] ? {
43
41
  readonly [K in string]: Ts<E>;
44
- } : never) : ConstTs<T>;
42
+ } : I extends readonly ['or', ...infer A extends readonly Type[]] ? Ts<A[number]> : never) : ConstTs<T>;
@@ -3,6 +3,7 @@ import { error, ok } from "../../result/module.f.js";
3
3
  import { isArray as commonIsArray } from "../../array/module.f.js";
4
4
  import { isObject as commonIsObject } from "../../object/module.f.js";
5
5
  import { identity } from "../../function/module.f.js";
6
+ import { todo } from "../../../dev/module.f.js";
6
7
  /**
7
8
  * Builds a validator for `array` or `record` schemas.
8
9
  * The inner item validator is instantiated lazily (only when the container is
@@ -36,20 +37,6 @@ const tag1Validate = ([tag, item]) => tag === 'array'
36
37
  : recordValidate(item);
37
38
  /** Validates a `Tag0` primitive schema using `typeof`. */
38
39
  const primitive0Validate = (tag) => value => typeof value === tag ? ok(value) : error('unexpected value');
39
- /** Validates a `Thunk` schema by evaluating it once and dispatching on the resulting `Info` tag. */
40
- const thunkValidate = (rtti) => {
41
- const info = rtti();
42
- const [tag, value] = info;
43
- switch (tag) {
44
- case 'const':
45
- return constValidate(value);
46
- case 'unknown':
47
- return ok;
48
- }
49
- return isTag1(tag)
50
- ? tag1Validate(info)
51
- : primitive0Validate(tag);
52
- };
53
40
  /**
54
41
  * Builds a validator for `Tuple` or `Struct` const schemas.
55
42
  * Iterates over the schema's entries and validates each corresponding
@@ -80,6 +67,18 @@ const constPrimitiveValidate = (rtti) => value => rtti === value
80
67
  const constValidate = (rtti) => typeof rtti === 'object' && rtti !== null
81
68
  ? constObjectValidate(rtti)
82
69
  : constPrimitiveValidate(rtti);
70
+ const orValidate = (rtti) => {
71
+ const all = rtti.map(r => validate(r));
72
+ return value => {
73
+ for (const i of all) {
74
+ const r = i(value);
75
+ if (r[0] === 'ok') {
76
+ return r;
77
+ }
78
+ }
79
+ return error('no match');
80
+ };
81
+ };
83
82
  /**
84
83
  * Creates a validator function for the given RTTI schema.
85
84
  *
@@ -97,12 +96,13 @@ const constValidate = (rtti) => typeof rtti === 'object' && rtti !== null
97
96
  */
98
97
  export const validate = (rtti) => {
99
98
  if (typeof rtti === 'function') {
100
- const [tag, value] = rtti();
99
+ const [tag, ...value] = rtti();
101
100
  switch (tag) {
102
- case 'const': return constValidate(value);
103
- case 'array': return arrayValidate(value);
104
- case 'record': return recordValidate(value);
101
+ case 'const': return constValidate(value[0]);
102
+ case 'array': return arrayValidate(value[0]);
103
+ case 'record': return recordValidate(value[0]);
105
104
  case 'unknown': return ok;
105
+ case 'or': return orValidate(value);
106
106
  }
107
107
  return primitive0Validate(tag);
108
108
  }
@@ -68,6 +68,20 @@ declare const _default: {
68
68
  constThunk: {
69
69
  primitive: () => void;
70
70
  };
71
+ or: {
72
+ consts: {
73
+ ok: () => void;
74
+ error: () => void;
75
+ };
76
+ thunks: {
77
+ ok: () => void;
78
+ error: () => void;
79
+ };
80
+ mixed: {
81
+ ok: () => void;
82
+ error: () => void;
83
+ };
84
+ };
71
85
  recursive: {
72
86
  arrayOfArrays: () => void;
73
87
  recordOfRecords: () => void;
@@ -1,5 +1,5 @@
1
1
  import { validate } from "./module.f.js";
2
- import { boolean, number, string, bigint, unknown, array, record } from "../module.f.js";
2
+ import { boolean, number, string, bigint, unknown, array, record, or } from "../module.f.js";
3
3
  const assertOk = ([k]) => { if (k !== 'ok') {
4
4
  throw 'expected ok';
5
5
  } };
@@ -154,6 +154,47 @@ export default {
154
154
  assertError(validate(t)(8n));
155
155
  },
156
156
  },
157
+ or: {
158
+ consts: {
159
+ ok: () => {
160
+ const t = or(...[false, 42, 'hello']);
161
+ assertOk(validate(t)(false));
162
+ assertOk(validate(t)(42));
163
+ assertOk(validate(t)('hello'));
164
+ },
165
+ error: () => {
166
+ const t = or(...[false, 42, 'hello']);
167
+ assertError(validate(t)(true));
168
+ assertError(validate(t)(43));
169
+ assertError(validate(t)('world'));
170
+ assertError(validate(t)(null));
171
+ },
172
+ },
173
+ thunks: {
174
+ ok: () => {
175
+ const t = or(number, string);
176
+ assertOk(validate(t)(42));
177
+ assertOk(validate(t)('hello'));
178
+ },
179
+ error: () => {
180
+ const t = or(number, string);
181
+ assertError(validate(t)(true));
182
+ assertError(validate(t)(null));
183
+ },
184
+ },
185
+ mixed: {
186
+ ok: () => {
187
+ const t = or(42, string);
188
+ assertOk(validate(t)(42));
189
+ assertOk(validate(t)('hello'));
190
+ },
191
+ error: () => {
192
+ const t = or(42, string);
193
+ assertError(validate(t)(43));
194
+ assertError(validate(t)(null));
195
+ },
196
+ },
197
+ },
157
198
  recursive: {
158
199
  arrayOfArrays: () => {
159
200
  // self-referential schema: an array whose elements are also arrays of the same type