liminal 0.12.2 → 0.13.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/dist/userJson.js CHANGED
@@ -2,5 +2,8 @@ import * as Effect from "effect/Effect";
2
2
  import { user } from "./user.js";
3
3
  import { encodeJsonc } from "./util/JsonValue.js";
4
4
  /** Stringify and append some JSON as a user message to the conversation. */
5
- export const userJson = (value, schema) => user `\`\`\`json${schema ? "c" : ""}\n${schema ? encodeJsonc(schema)(value) : JSON.stringify(value, null, 2)}\n\`\`\``;
5
+ export const userJson = Effect.fnUntraced(function* (value, schema) {
6
+ const encoded = schema ? encodeJsonc(schema)(value) : JSON.stringify(value, null, 2);
7
+ return yield* user `\`\`\`json${schema ? "c" : ""}${"\n"}${encoded}${"\n"}\`\`\``;
8
+ });
6
9
  //# sourceMappingURL=userJson.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"userJson.js","sourceRoot":"","sources":["../userJson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAkB,MAAM,qBAAqB,CAAA;AAEjE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAG4B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CACjE,IAAI,CAAA,aAAa,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA"}
1
+ {"version":3,"file":"userJson.js","sourceRoot":"","sources":["../userJson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAkB,MAAM,qBAAqB,CAAA;AAEjE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAG4B,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAC,KAAK,EAAE,MAAM;IACxF,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IACpF,OAAO,KAAK,CAAC,CAAC,IAAI,CAAA,aAAa,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,QAAQ,CAAA;AAClF,CAAC,CAAC,CAAA"}
@@ -1,7 +1,8 @@
1
+ import * as Effect from "effect/Effect";
1
2
  import * as Schema from "effect/Schema";
2
3
  export type JsonValue = null | boolean | number | string | JsonValueArray | JsonValueObject;
3
4
  export type JsonValueArray = Array<JsonValue> | ReadonlyArray<JsonValue>;
4
5
  export type JsonValueObject = {
5
6
  [key: string]: JsonValue;
6
7
  };
7
- export declare const encodeJsonc: <A, I extends JsonValue>(schema: Schema.Schema<A, I>) => (value: A) => string;
8
+ export declare const encodeJsonc: <A, I extends JsonValue>(schema: Schema.Schema<A, I>) => (value: A) => Effect.Effect<string>;
@@ -1,7 +1,10 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { pipe } from "effect/Function";
3
+ import * as Option from "effect/Option";
1
4
  import * as Schema from "effect/Schema";
2
5
  import * as SchemaAST from "effect/SchemaAST";
3
6
  export const encodeJsonc = (schema) => {
4
- const encoder = encodeAstJsonc(SchemaAST.encodedAST(schema.ast));
7
+ const encoder = encodeAst(SchemaAST.encodedBoundAST(schema.ast));
5
8
  return (value) => encoder(value, new EncodeJsoncContext(0));
6
9
  };
7
10
  class EncodeJsoncContext {
@@ -14,69 +17,93 @@ class EncodeJsoncContext {
14
17
  this.childIndentation = " ".repeat((depth + 1) * 2);
15
18
  }
16
19
  next = () => new EncodeJsoncContext(this.depth + 1);
17
- comment = (type) => {
18
- const description = extractAnnotation(type)?.trim();
19
- if (description) {
20
- return `// ${description}\n${this.childIndentation}`;
21
- }
22
- return "";
23
- };
20
+ comment = (type) => Option.match(SchemaAST.getDescriptionAnnotation(type), {
21
+ onSome: (v) => {
22
+ v = v.trim();
23
+ if (v) {
24
+ return `// ${v}\n${this.childIndentation}`;
25
+ }
26
+ return "";
27
+ },
28
+ onNone: () => "",
29
+ });
24
30
  }
25
- const encodeAstJsonc = (ast) => {
31
+ const encodeAst = (ast, refinement) => {
26
32
  switch (ast._tag) {
27
33
  case "TypeLiteral": {
28
- return (value, ctx) => {
29
- const props = ast.propertySignatures
30
- .map(({ name, type }) => {
34
+ return Effect.fnUntraced(function* (value, ctx) {
35
+ const props = yield* Effect.all(ast.propertySignatures.map(Effect.fnUntraced(function* ({ name, type }) {
31
36
  if (typeof name === "symbol")
32
37
  throw 0;
33
- const child = encodeAstJsonc(type)(value[name], ctx.next());
34
- return `${ctx.comment(type)}${name}: ${child}`;
35
- })
36
- .join(`,\n${ctx.childIndentation}`);
38
+ const child = yield* encodeAst(type)(value[name], ctx.next());
39
+ return `${ctx.comment(refinement ?? type)}${name}: ${child}`;
40
+ }))).pipe(Effect.map((v) => v.join(`,\n${ctx.childIndentation}`)));
37
41
  return `{\n${ctx.childIndentation}${props}\n${ctx.indentation}}`;
38
- };
42
+ });
39
43
  }
40
44
  case "StringKeyword": {
41
- return (value) => `"${value}"`;
45
+ return (value) => Effect.succeed(`"${value}"`);
42
46
  }
47
+ case "BooleanKeyword":
43
48
  case "NumberKeyword": {
44
- return (value) => `${value}`;
49
+ return (value) => Effect.succeed(String(value));
50
+ }
51
+ case "Refinement": {
52
+ return encodeAst(ast.from, refinement ?? ast);
53
+ }
54
+ case "UnknownKeyword":
55
+ case "AnyKeyword": {
56
+ return (value, ctx) => Effect.succeed(JSON
57
+ .stringify(value, null, 2)
58
+ .split("\n")
59
+ .map((line, i) => i ? ctx.indentation.concat(line) : line)
60
+ .join("\n"));
61
+ }
62
+ case "Union": {
63
+ const { types } = ast;
64
+ const guards = types.map((ast) => pipe(ast, Schema.make, Schema.is));
65
+ return (value, ctx) => {
66
+ for (let i = 0; i < types.length; i++) {
67
+ const guard = guards[i];
68
+ if (guard(value)) {
69
+ return encodeAst(types[i])(value, ctx);
70
+ }
71
+ }
72
+ throw 0;
73
+ };
45
74
  }
46
75
  case "Literal": {
47
76
  const { literal } = ast;
48
- if (typeof literal === "string") {
49
- return () => `"${literal}"`;
50
- }
51
- if (typeof literal === "number" || typeof literal === "boolean") {
52
- return () => String(literal);
53
- }
54
- if (literal === null) {
55
- return () => "null";
56
- }
57
- throw 0;
77
+ const v = (() => {
78
+ switch (typeof literal) {
79
+ case "boolean":
80
+ case "number": {
81
+ return String(literal);
82
+ }
83
+ case "string": {
84
+ return `"${literal}"`;
85
+ }
86
+ }
87
+ if (literal === null) {
88
+ return "null";
89
+ }
90
+ console.log({ literal });
91
+ throw 0;
92
+ })();
93
+ return () => Effect.succeed(v);
58
94
  }
59
95
  case "TupleType": {
60
96
  const { elements, rest } = ast;
61
- return (value, ctx) => {
62
- const e = (elements.length ? elements : rest).map((element, i) => {
63
- const child = encodeAstJsonc(element.type)(value[i], ctx.next());
64
- return `${ctx.comment(element.type)}${child}`;
65
- }).join(`,\n${ctx.childIndentation}`);
66
- return `[\n${ctx.childIndentation}${e}\n${ctx.indentation}]`;
67
- };
97
+ return (value, ctx) => Effect.all((elements.length ? elements : rest).map(Effect.fnUntraced(function* (element, i) {
98
+ const child = yield* encodeAst(element.type)(value[i], ctx.next());
99
+ return `${ctx.comment(refinement ?? element.type)}${child}`;
100
+ }))).pipe(Effect.map((v) => `[\n${ctx.childIndentation}${v.join(`,\n${ctx.childIndentation}`)}\n${ctx.indentation}]`));
68
101
  }
69
- }
70
- console.log(ast._tag);
71
- throw 0;
72
- };
73
- const extractAnnotation = ({ annotations }) => {
74
- if (SchemaAST.JSONSchemaAnnotationId in annotations) {
75
- const jsonSchemaAnnotations = annotations[SchemaAST.JSONSchemaAnnotationId];
76
- if (jsonSchemaAnnotations) {
77
- return jsonSchemaAnnotations.description;
102
+ case "Suspend": {
103
+ return encodeAst(ast.f());
78
104
  }
79
105
  }
80
- return;
106
+ console.log({ ast });
107
+ throw 0;
81
108
  };
82
109
  //# sourceMappingURL=JsonValue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonValue.js","sourceRoot":"","sources":["../../util/JsonValue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"JsonValue.js","sourceRoot":"","sources":["../../util/JsonValue.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@ import * as Effect from "effect/Effect";
2
2
  /** Append a user message to the conversation. */
3
3
  export type Taggable<A, E, R> = <L extends Array<unknown>, E1 = never, R1 = never>(template?: TemplateStringsArray | string | Effect.Effect<string | undefined, E1, R1> | undefined, ...substitutions: L) => Effect.Effect<A, ([ExtractEffect<L>] extends [never] ? never : Effect.Effect.Error<ExtractEffect<L>>) | E | E1, ([ExtractEffect<L>] extends [never] ? never : Effect.Effect.Context<ExtractEffect<L>>) | R | R1>;
4
4
  type ExtractEffect<T extends Array<unknown>> = Extract<T[number], Effect.All.EffectAny>;
5
- export declare const normalize: <A0 extends TemplateStringsArray | string | Effect.Effect<string | undefined, any, any> | undefined, L extends Array<unknown>>(a0: A0, ...aRest: L) => Effect.Effect<string | (undefined extends A0 ? undefined : never)>;
5
+ export declare const normalize: <A0 extends TemplateStringsArray | string | Effect.Effect<string | undefined, any, any> | undefined, L extends Array<unknown>>(a0: A0, aRest: L) => Effect.Effect<string | (undefined extends A0 ? undefined : never)>;
6
6
  export {};
@@ -1,5 +1,6 @@
1
1
  import * as Effect from "effect/Effect";
2
- export const normalize = Effect.fnUntraced(function* (a0, ...aRest) {
2
+ import { fixRaw } from "./fixRaw.js";
3
+ export const normalize = Effect.fnUntraced(function* (a0, aRest) {
3
4
  let a0_;
4
5
  if (Effect.isEffect(a0)) {
5
6
  a0_ = yield* a0;
@@ -9,13 +10,15 @@ export const normalize = Effect.fnUntraced(function* (a0, ...aRest) {
9
10
  }
10
11
  if (!a0_)
11
12
  return undefined;
12
- const aRest_ = yield* Effect.all(aRest.map((v) => Effect.isEffect(v) ? v : Effect.succeed(v)));
13
+ const aRest_ = yield* Effect.all(aRest.map((v) => Effect.isEffect(v)
14
+ ? v
15
+ : Effect.succeed(v)));
13
16
  if (typeof a0_ === "string") {
14
17
  if (aRest_.length === 0) {
15
18
  return a0_;
16
19
  }
17
20
  return [a0_, ...aRest_].join("");
18
21
  }
19
- return String.raw(a0_, ...aRest);
22
+ return fixRaw(a0_, aRest_);
20
23
  });
21
24
  //# sourceMappingURL=Taggable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Taggable.js","sourceRoot":"","sources":["../../util/Taggable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAkBvC,MAAM,CAAC,MAAM,SAAS,GAUoD,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAC,EAAE,EAAE,GAAG,KAAK;IAChH,IAAI,GAA8C,CAAA;IAClD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACxB,GAAG,GAAG,KAAK,CAAC,CAAC,EAA8D,CAAA;IAC7E,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,EAAE,CAAA;IACV,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAkB,CAAA;IACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAC9B,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CACnB,CAAA;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAA;AAClC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"Taggable.js","sourceRoot":"","sources":["../../util/Taggable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAkBpC,MAAM,CAAC,MAAM,SAAS,GAUoD,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAC,EAAE,EAAE,KAAK;IAC7G,IAAI,GAA8C,CAAA;IAClD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACxB,GAAG,GAAG,KAAK,CAAC,CAAC,EAA8D,CAAA;IAC7E,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,EAAE,CAAA;IACV,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAkB,CAAA;IACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAC9B,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACd,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CACtB,CACwC,CAAA;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AAC5B,CAAC,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export declare const fixRaw: (strings: TemplateStringsArray, values: Array<unknown>) => string;
2
+ export declare const fixTemplateStrings: (template: TemplateStringsArray) => {
3
+ readonly raw: readonly string[];
4
+ };
@@ -0,0 +1,75 @@
1
+ const LEADING_SPACE_RE = /^([ \t]*)/;
2
+ const INDENTATION_RE = /^\n([ \t]+)/;
3
+ const ESCAPE_SEQ_RE = /\\([`${\\]|\n)/g;
4
+ const LAST_INDENTATION_RE = /\n[ \t]+$/;
5
+ export const fixRaw = (strings, values) => {
6
+ const fixedStrings = fixTemplateStrings(strings);
7
+ const rawArr = fixedStrings.raw;
8
+ const valuesLength = values.length;
9
+ const resultParts = new Array(Math.max(1, rawArr.length * 2 - 1));
10
+ let resultIndex = 0;
11
+ for (let i = 0; i < rawArr.length; i++) {
12
+ const str = rawArr[i] || "";
13
+ resultParts[resultIndex++] = str;
14
+ // Only process values for non-final segments.
15
+ if (i < valuesLength) {
16
+ const value = String(values[i]);
17
+ // If value has line breaks, we should indent it.
18
+ if (value.includes("\n")) {
19
+ const lastNewlineIndex = str.lastIndexOf("\n");
20
+ if (lastNewlineIndex !== -1) {
21
+ // Extract the indentation after the last newline.
22
+ const textAfterLastNewline = str.substring(lastNewlineIndex + 1);
23
+ const leadingSpaceMatch = LEADING_SPACE_RE.exec(textAfterLastNewline);
24
+ const indentationToApply = leadingSpaceMatch && leadingSpaceMatch[1] ? leadingSpaceMatch[1] : "";
25
+ if (indentationToApply) {
26
+ // Split the value into lines once.
27
+ const lines = value.split("\n");
28
+ const linesLength = lines.length;
29
+ // First line doesn't need indentation.
30
+ resultParts[resultIndex++] = lines[0];
31
+ // Apply indentation to subsequent lines.
32
+ for (let j = 1; j < linesLength; j++) {
33
+ resultParts[resultIndex++] = "\n" + indentationToApply + lines[j];
34
+ }
35
+ continue;
36
+ }
37
+ }
38
+ }
39
+ // For simple values or when no indentation is needed.
40
+ resultParts[resultIndex++] = value;
41
+ }
42
+ }
43
+ // Combine all parts at once
44
+ return resultParts.slice(0, resultIndex).join("");
45
+ };
46
+ export const fixTemplateStrings = (template) => {
47
+ const leadingIndentMatch = INDENTATION_RE.exec(template.raw[0]);
48
+ const indentation = leadingIndentMatch?.[1];
49
+ const rawLength = template.raw.length;
50
+ const raw = new Array(rawLength);
51
+ for (let i = 0; i < rawLength; i++) {
52
+ let str = template.raw[i];
53
+ // Only perform common indentation replacements if needed.
54
+ if (indentation) {
55
+ // Remove leading newline and indentation in the first segment.
56
+ if (i === 0) {
57
+ str = str.slice(indentation.length + 1);
58
+ }
59
+ // Use a simple string replacement with a regular expression for better performance.
60
+ str = str.replaceAll(`\n${indentation}`, "\n");
61
+ }
62
+ // Replace common escape sequences in a single pass.
63
+ str = str.replace(ESCAPE_SEQ_RE, (_match, char) => {
64
+ // Keep the escaped newline replacement separate for clarity.
65
+ return char === "\n" ? "" : char;
66
+ });
67
+ // Handle trailing spaces only for the last segment.
68
+ if (indentation && i === rawLength - 1) {
69
+ str = str.replace(LAST_INDENTATION_RE, "");
70
+ }
71
+ raw[i] = str;
72
+ }
73
+ return { raw };
74
+ };
75
+ //# sourceMappingURL=fixRaw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixRaw.js","sourceRoot":"","sources":["../../util/fixRaw.ts"],"names":[],"mappings":"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"}
package/handle.ts CHANGED
@@ -6,7 +6,7 @@ import type { LEvent } from "./LEvent.ts"
6
6
  import { Strand } from "./Strand.ts"
7
7
 
8
8
  /** Attach an event handler to process the events of the current strand. */
9
- export const handle: <A, E, R>(
9
+ export const listen: <A, E, R>(
10
10
  f: (event: LEvent) => Effect.Effect<A, E, R>,
11
11
  ) => Effect.Effect<RuntimeFiber<void, E>, never, Strand | R | Scope.Scope> = Effect.fnUntraced(function*(f) {
12
12
  const latch = yield* Effect.makeLatch(false)
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "access": "public",
8
8
  "provenance": true
9
9
  },
10
- "version": "0.12.2",
10
+ "version": "0.13.0",
11
11
  "license": "Apache-2.0",
12
12
  "repository": {
13
13
  "type": "git",
package/userJson.ts CHANGED
@@ -8,5 +8,7 @@ import { encodeJsonc, type JsonValue } from "./util/JsonValue.ts"
8
8
  export const userJson: <A, I extends JsonValue>(
9
9
  value: A,
10
10
  schema?: Schema.Schema<A, I>,
11
- ) => Effect.Effect<void, never, Strand.Strand> = (value, schema) =>
12
- user`\`\`\`json${schema ? "c" : ""}\n${schema ? encodeJsonc(schema)(value) : JSON.stringify(value, null, 2)}\n\`\`\``
11
+ ) => Effect.Effect<void, never, Strand.Strand> = Effect.fnUntraced(function*(value, schema) {
12
+ const encoded = schema ? encodeJsonc(schema)(value) : JSON.stringify(value, null, 2)
13
+ return yield* user`\`\`\`json${schema ? "c" : ""}${"\n"}${encoded}${"\n"}\`\`\``
14
+ })
package/util/JsonValue.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import * as Effect from "effect/Effect"
2
+ import { pipe } from "effect/Function"
3
+ import * as Option from "effect/Option"
1
4
  import * as Schema from "effect/Schema"
2
5
  import * as SchemaAST from "effect/SchemaAST"
3
6
 
@@ -7,10 +10,10 @@ export type JsonValueArray = Array<JsonValue> | ReadonlyArray<JsonValue>
7
10
 
8
11
  export type JsonValueObject = { [key: string]: JsonValue }
9
12
 
10
- export const encodeJsonc: <A, I extends JsonValue>(schema: Schema.Schema<A, I>) => (value: A) => string = (
11
- schema,
12
- ) => {
13
- const encoder = encodeAstJsonc(SchemaAST.encodedAST(schema.ast))
13
+ export const encodeJsonc: <A, I extends JsonValue>(
14
+ schema: Schema.Schema<A, I>,
15
+ ) => (value: A) => Effect.Effect<string> = (schema) => {
16
+ const encoder = encodeAst(SchemaAST.encodedBoundAST(schema.ast))
14
17
  return (value) => encoder(value, new EncodeJsoncContext(0))
15
18
  }
16
19
 
@@ -26,72 +29,116 @@ class EncodeJsoncContext {
26
29
 
27
30
  next = () => new EncodeJsoncContext(this.depth + 1)
28
31
 
29
- comment = (type: SchemaAST.AST): string => {
30
- const description = extractAnnotation(type)?.trim()
31
- if (description) {
32
- return `// ${description}\n${this.childIndentation}`
33
- }
34
- return ""
35
- }
32
+ comment = (type: SchemaAST.AST): string =>
33
+ Option.match(SchemaAST.getDescriptionAnnotation(type), {
34
+ onSome: (v) => {
35
+ v = v.trim()
36
+ if (v) {
37
+ return `// ${v}\n${this.childIndentation}`
38
+ }
39
+ return ""
40
+ },
41
+ onNone: () => "",
42
+ })
36
43
  }
37
44
 
38
- const encodeAstJsonc: (ast: SchemaAST.AST) => (value: unknown, ctx: EncodeJsoncContext) => string = (ast) => {
45
+ const encodeAst: (
46
+ ast: SchemaAST.AST,
47
+ refinement?: SchemaAST.Refinement,
48
+ ) => (value: unknown, ctx: EncodeJsoncContext) => Effect.Effect<string> = (ast, refinement) => {
39
49
  switch (ast._tag) {
40
50
  case "TypeLiteral": {
41
- return (value, ctx) => {
42
- const props = ast.propertySignatures
43
- .map(({ name, type }) => {
44
- if (typeof name === "symbol") throw 0
45
-
46
- const child = encodeAstJsonc(type)((value as never)[name], ctx.next())
47
- return `${ctx.comment(type)}${name}: ${child}`
48
- })
49
- .join(`,\n${ctx.childIndentation}`)
51
+ return Effect.fnUntraced(function*(value, ctx) {
52
+ const props = yield* Effect.all(
53
+ ast.propertySignatures.map(
54
+ Effect.fnUntraced(function*({ name, type }) {
55
+ if (typeof name === "symbol") throw 0
56
+ const child = yield* encodeAst(type)((value as never)[name], ctx.next())
57
+ return `${ctx.comment(refinement ?? type)}${name}: ${child}`
58
+ }),
59
+ ),
60
+ ).pipe(
61
+ Effect.map((v) => v.join(`,\n${ctx.childIndentation}`)),
62
+ )
50
63
  return `{\n${ctx.childIndentation}${props}\n${ctx.indentation}}`
51
- }
64
+ })
52
65
  }
53
66
  case "StringKeyword": {
54
- return (value) => `"${value}"`
67
+ return (value) => Effect.succeed(`"${value}"`)
55
68
  }
69
+ case "BooleanKeyword":
56
70
  case "NumberKeyword": {
57
- return (value) => `${value}`
71
+ return (value) => Effect.succeed(String(value))
72
+ }
73
+ case "Refinement": {
74
+ return encodeAst(ast.from, refinement ?? ast)
75
+ }
76
+ case "UnknownKeyword":
77
+ case "AnyKeyword": {
78
+ return (value, ctx) =>
79
+ Effect.succeed(
80
+ JSON
81
+ .stringify(value, null, 2)
82
+ .split("\n")
83
+ .map((line, i) => i ? ctx.indentation.concat(line) : line)
84
+ .join("\n"),
85
+ )
86
+ }
87
+ case "Union": {
88
+ const { types } = ast
89
+ const guards = types.map((ast) =>
90
+ pipe(
91
+ ast,
92
+ Schema.make,
93
+ Schema.is,
94
+ )
95
+ )
96
+ return (value, ctx) => {
97
+ for (let i = 0; i < types.length; i++) {
98
+ const guard = guards[i]!
99
+ if (guard(value)) {
100
+ return encodeAst(types[i]!)(value, ctx)
101
+ }
102
+ }
103
+ throw 0
104
+ }
58
105
  }
59
106
  case "Literal": {
60
107
  const { literal } = ast
61
- if (typeof literal === "string") {
62
- return () => `"${literal}"`
63
- }
64
- if (typeof literal === "number" || typeof literal === "boolean") {
65
- return () => String(literal)
66
- }
67
- if (literal === null) {
68
- return () => "null"
69
- }
70
- throw 0
108
+ const v = (() => {
109
+ switch (typeof literal) {
110
+ case "boolean":
111
+ case "number": {
112
+ return String(literal)
113
+ }
114
+ case "string": {
115
+ return `"${literal}"`
116
+ }
117
+ }
118
+ if (literal === null) {
119
+ return "null"
120
+ }
121
+ console.log({ literal })
122
+ throw 0
123
+ })()
124
+ return () => Effect.succeed(v)
71
125
  }
72
126
  case "TupleType": {
73
127
  const { elements, rest } = ast
74
- return (value, ctx) => {
75
- const e = (elements.length ? elements : rest).map((element, i) => {
76
- const child = encodeAstJsonc(element.type)((value as never)[i]!, ctx.next())
77
- return `${ctx.comment(element.type)}${child}`
78
- }).join(`,\n${ctx.childIndentation}`)
79
- return `[\n${ctx.childIndentation}${e}\n${ctx.indentation}]`
80
- }
128
+ return (value, ctx) =>
129
+ Effect.all((elements.length ? elements : rest).map(
130
+ Effect.fnUntraced(function*(element, i) {
131
+ const child = yield* encodeAst(element.type)((value as never)[i]!, ctx.next())
132
+ return `${ctx.comment(refinement ?? element.type)}${child}`
133
+ }),
134
+ )).pipe(
135
+ Effect.map((v) => `[\n${ctx.childIndentation}${v.join(`,\n${ctx.childIndentation}`)}\n${ctx.indentation}]`),
136
+ )
81
137
  }
82
- }
83
- console.log(ast._tag)
84
- throw 0
85
- }
86
-
87
- const extractAnnotation = ({ annotations }: SchemaAST.AST): string | undefined => {
88
- if (SchemaAST.JSONSchemaAnnotationId in annotations) {
89
- const jsonSchemaAnnotations = annotations[SchemaAST.JSONSchemaAnnotationId] as
90
- | SchemaAST.Annotations
91
- | undefined
92
- if (jsonSchemaAnnotations) {
93
- return jsonSchemaAnnotations.description as string
138
+ case "Suspend": {
139
+ return encodeAst(ast.f())
94
140
  }
95
141
  }
96
- return
142
+ console.log({ ast })
143
+ throw 0
97
144
  }
package/util/Taggable.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Effect from "effect/Effect"
2
+ import { fixRaw } from "./fixRaw.ts"
2
3
 
3
4
  /** Append a user message to the conversation. */
4
5
  export type Taggable<A, E, R> = <L extends Array<unknown>, E1 = never, R1 = never>(
@@ -25,8 +26,8 @@ export const normalize: <
25
26
  L extends Array<unknown>,
26
27
  >(
27
28
  a0: A0,
28
- ...aRest: L
29
- ) => Effect.Effect<string | (undefined extends A0 ? undefined : never)> = Effect.fnUntraced(function*(a0, ...aRest) {
29
+ aRest: L,
30
+ ) => Effect.Effect<string | (undefined extends A0 ? undefined : never)> = Effect.fnUntraced(function*(a0, aRest) {
30
31
  let a0_: TemplateStringsArray | string | undefined
31
32
  if (Effect.isEffect(a0)) {
32
33
  a0_ = yield* a0 as Effect.Effect<TemplateStringsArray | string | undefined>
@@ -35,7 +36,11 @@ export const normalize: <
35
36
  }
36
37
  if (!a0_) return undefined as never
37
38
  const aRest_ = yield* Effect.all(
38
- aRest.map((v) => Effect.isEffect(v) ? v : Effect.succeed(v)),
39
+ aRest.map((v) =>
40
+ Effect.isEffect(v)
41
+ ? v
42
+ : Effect.succeed(v)
43
+ ),
39
44
  ) as never as Effect.Effect<Array<unknown>>
40
45
  if (typeof a0_ === "string") {
41
46
  if (aRest_.length === 0) {
@@ -43,5 +48,5 @@ export const normalize: <
43
48
  }
44
49
  return [a0_, ...aRest_].join("")
45
50
  }
46
- return String.raw(a0_, ...aRest)
51
+ return fixRaw(a0_, aRest_)
47
52
  })