liminal 0.9.0 → 0.11.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/CHANGELOG.md +12 -0
- package/L.ts +14 -81
- package/LEvent.ts +23 -0
- package/Sequence.ts +14 -0
- package/Strand.ts +19 -41
- package/append.ts +13 -0
- package/assistant.ts +23 -0
- package/assistantStruct.ts +34 -0
- package/branch.ts +26 -0
- package/clear.ts +15 -0
- package/dist/L.d.ts +14 -15
- package/dist/L.js +14 -56
- package/dist/L.js.map +1 -1
- package/dist/LEvent.d.ts +26 -0
- package/dist/LEvent.js +16 -0
- package/dist/LEvent.js.map +1 -0
- package/dist/Sequence.d.ts +2 -0
- package/dist/Sequence.js +2 -0
- package/dist/Sequence.js.map +1 -0
- package/dist/Strand.d.ts +20 -20
- package/dist/Strand.js +3 -19
- package/dist/Strand.js.map +1 -1
- package/dist/append.d.ts +5 -0
- package/dist/append.js +11 -0
- package/dist/append.js.map +1 -0
- package/dist/assistant.d.ts +6 -0
- package/dist/assistant.js +20 -0
- package/dist/assistant.js.map +1 -0
- package/dist/assistantStruct.d.ts +12 -0
- package/dist/assistantStruct.js +22 -0
- package/dist/assistantStruct.js.map +1 -0
- package/dist/branch.d.ts +4 -0
- package/dist/branch.js +18 -0
- package/dist/branch.js.map +1 -0
- package/dist/clear.d.ts +5 -0
- package/dist/clear.js +15 -0
- package/dist/clear.js.map +1 -0
- package/dist/events.d.ts +5 -0
- package/dist/events.js +6 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/JsonValue.d.ts +5 -0
- package/dist/internal/JsonValue.js +2 -0
- package/dist/internal/JsonValue.js.map +1 -0
- package/dist/internal/Taggable.d.ts +11 -0
- package/dist/internal/Taggable.js +2 -0
- package/dist/internal/Taggable.js.map +1 -0
- package/dist/messages.d.ts +5 -0
- package/dist/messages.js +5 -0
- package/dist/messages.js.map +1 -0
- package/dist/pretty.d.ts +2 -0
- package/dist/pretty.js +37 -0
- package/dist/pretty.js.map +1 -0
- package/dist/reduce.d.ts +4 -0
- package/dist/reduce.js +20 -0
- package/dist/reduce.js.map +1 -0
- package/dist/sequence_.d.ts +2 -0
- package/dist/sequence_.js +5 -0
- package/dist/sequence_.js.map +1 -0
- package/dist/strand_.d.ts +4 -0
- package/dist/strand_.js +18 -0
- package/dist/strand_.js.map +1 -0
- package/dist/system.d.ts +5 -0
- package/dist/system.js +11 -0
- package/dist/system.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/user.d.ts +5 -0
- package/dist/user.js +14 -0
- package/dist/user.js.map +1 -0
- package/dist/userJson.d.ts +6 -0
- package/dist/userJson.js +8 -0
- package/dist/userJson.js.map +1 -0
- package/events.ts +9 -0
- package/index.ts +3 -1
- package/internal/JsonValue.ts +5 -0
- package/internal/Taggable.ts +17 -0
- package/messages.ts +9 -0
- package/package.json +10 -6
- package/pretty.ts +41 -0
- package/reduce.ts +32 -0
- package/sequence_.ts +9 -0
- package/strand_.ts +25 -0
- package/system.ts +13 -0
- package/tsconfig.json +11 -1
- package/user.ts +17 -0
- package/userJson.ts +12 -0
- package/dist/util/JSONValue.d.ts +0 -5
- package/dist/util/JSONValue.js +0 -2
- package/dist/util/JSONValue.js.map +0 -1
- package/dist/util/fixTemplateStrings.d.ts +0 -11
- package/dist/util/fixTemplateStrings.js +0 -83
- package/dist/util/fixTemplateStrings.js.map +0 -1
- package/dist/util/isTemplateStringsArray.d.ts +0 -1
- package/dist/util/isTemplateStringsArray.js +0 -4
- package/dist/util/isTemplateStringsArray.js.map +0 -1
- package/util/JSONValue.ts +0 -5
- package/util/fixTemplateStrings.ts +0 -99
- package/util/isTemplateStringsArray.ts +0 -3
package/dist/user.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { type Taggable } from "./internal/Taggable.ts";
|
|
3
|
+
import * as Strand from "./Strand.ts";
|
|
4
|
+
/** Append a user message to the conversation. */
|
|
5
|
+
export declare const user: Taggable<Effect.Effect<void, never, Strand.Strand>>;
|
package/dist/user.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TextPart, UserMessage } from "@effect/ai/AiInput";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import { append } from "./append.js";
|
|
4
|
+
import { normalize } from "./internal/Taggable.js";
|
|
5
|
+
import * as Strand from "./Strand.js";
|
|
6
|
+
/** Append a user message to the conversation. */
|
|
7
|
+
export const user = (a0, ...aRest) => append(UserMessage.make({
|
|
8
|
+
parts: [
|
|
9
|
+
TextPart.make({
|
|
10
|
+
text: normalize(a0, aRest),
|
|
11
|
+
}),
|
|
12
|
+
],
|
|
13
|
+
}));
|
|
14
|
+
//# sourceMappingURL=user.js.map
|
package/dist/user.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAiB,MAAM,wBAAwB,CAAA;AACjE,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,iDAAiD;AACjD,MAAM,CAAC,MAAM,IAAI,GAAwD,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,CACxF,MAAM,CACJ,WAAW,CAAC,IAAI,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC;SAC3B,CAAC;KACH;CACF,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import type { JsonValueObject } from "./internal/JsonValue.ts";
|
|
4
|
+
import * as Strand from "./Strand.ts";
|
|
5
|
+
/** Stringify and append some JSON as a user message to the conversation. */
|
|
6
|
+
export declare const userJson: <A, I extends JsonValueObject>(value: A, schema?: Schema.Schema<A, I, never>) => Effect.Effect<void, never, Strand.Strand>;
|
package/dist/userJson.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import * as Strand from "./Strand.js";
|
|
4
|
+
import { user } from "./user.js";
|
|
5
|
+
// TODO: serialize with comments from schema
|
|
6
|
+
/** Stringify and append some JSON as a user message to the conversation. */
|
|
7
|
+
export const userJson = (value) => user `\`\`\`jsonc\n${JSON.stringify(value, null, 2)}\n\`\`\``;
|
|
8
|
+
//# sourceMappingURL=userJson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userJson.js","sourceRoot":"","sources":["../userJson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,4CAA4C;AAC5C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAG4B,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA"}
|
package/events.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Stream from "effect/Stream"
|
|
3
|
+
import type { LEvent } from "./LEvent"
|
|
4
|
+
import { Strand } from "./Strand.ts"
|
|
5
|
+
|
|
6
|
+
/** Get a new event stream of the events of the current strand. */
|
|
7
|
+
export const events: Stream.Stream<LEvent, never, Strand> = Stream.unwrap(
|
|
8
|
+
Effect.map(Strand, ({ events }) => Stream.fromPubSub(events)),
|
|
9
|
+
)
|
package/index.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type Taggable<T> = {
|
|
2
|
+
(value: string): T
|
|
3
|
+
(template: TemplateStringsArray, ...substitutions: Array<unknown>): T
|
|
4
|
+
(template: string | TemplateStringsArray, ...substitutions: Array<unknown>): T
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type TaggableNullable<T> = {
|
|
8
|
+
(value?: string | undefined): T
|
|
9
|
+
(template: TemplateStringsArray, ...substitutions: Array<unknown>): T
|
|
10
|
+
(template?: string | TemplateStringsArray | undefined, ...substitutions: Array<unknown>): T
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const normalize = <A0 extends string | TemplateStringsArray | undefined>(
|
|
14
|
+
a0: A0,
|
|
15
|
+
aRest: Array<unknown> = [],
|
|
16
|
+
): string | (undefined extends A0 ? undefined : never) =>
|
|
17
|
+
a0 ? typeof a0 === "string" ? a0 : String.raw(a0, aRest) : undefined as never
|
package/messages.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Message } from "@effect/ai/AiInput"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import { Strand } from "./Strand.ts"
|
|
4
|
+
|
|
5
|
+
/** Get a copy of the current list of messages. */
|
|
6
|
+
export const messages: Effect.Effect<Array<Message>, never, Strand> = Effect.map(
|
|
7
|
+
Strand,
|
|
8
|
+
({ messages: [...messages] }) => messages,
|
|
9
|
+
)
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liminal",
|
|
3
|
+
"homepage": "https://liminal.land",
|
|
4
|
+
"llms": "https://liminal.land/llms.txt",
|
|
5
|
+
"llmsFull": "https://liminal.land/llmsFull.txt",
|
|
3
6
|
"publishConfig": {
|
|
4
|
-
"access": "public"
|
|
7
|
+
"access": "public",
|
|
8
|
+
"provenance": true
|
|
5
9
|
},
|
|
6
|
-
"version": "0.
|
|
10
|
+
"version": "0.11.0",
|
|
7
11
|
"license": "Apache-2.0",
|
|
8
12
|
"repository": {
|
|
9
13
|
"type": "git",
|
|
@@ -11,14 +15,14 @@
|
|
|
11
15
|
"directory": "liminal"
|
|
12
16
|
},
|
|
13
17
|
"type": "module",
|
|
18
|
+
"sideEffects": false,
|
|
14
19
|
"description": "Primitives for composing conversation trees with language models and TypeScript iterators.",
|
|
15
20
|
"exports": {
|
|
16
|
-
".": "./
|
|
17
|
-
"./
|
|
18
|
-
"./Strand": "./dist/Strand.js"
|
|
21
|
+
".": "./index.ts",
|
|
22
|
+
"./package.json": "./package.json"
|
|
19
23
|
},
|
|
20
24
|
"peerDependencies": {
|
|
21
25
|
"@effect/ai": "^0.18.16",
|
|
22
|
-
"effect": "^3.17.
|
|
26
|
+
"effect": "^3.17.4"
|
|
23
27
|
}
|
|
24
28
|
}
|
package/pretty.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Message } from "@effect/ai/AiInput"
|
|
2
|
+
import type { LEvent } from "./LEvent.ts"
|
|
3
|
+
|
|
4
|
+
const GRAY = "\x1b[90m"
|
|
5
|
+
const RESET = "\x1b[0m"
|
|
6
|
+
const BOLD = "\x1b[1m"
|
|
7
|
+
const GRAY_BG = "\x1b[47m"
|
|
8
|
+
|
|
9
|
+
export const pretty: (event: typeof LEvent["Type"]) => string = (event) => {
|
|
10
|
+
let text = `${GRAY}${event._tag}${RESET}`
|
|
11
|
+
switch (event._tag) {
|
|
12
|
+
case "MessagesAppended": {
|
|
13
|
+
text += event.messages.map(formatMessage).join("\n")
|
|
14
|
+
break
|
|
15
|
+
}
|
|
16
|
+
case "MessagesCleared": {
|
|
17
|
+
text += `\n${event.cleared.length} messages cleared.`
|
|
18
|
+
break
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return text
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const formatMessage = ({ _tag, parts }: Message): string => {
|
|
25
|
+
let value = ""
|
|
26
|
+
for (const part of parts) {
|
|
27
|
+
value += `\n${BOLD}${_tag}\n${GRAY_BG}`
|
|
28
|
+
switch (part._tag) {
|
|
29
|
+
case "TextPart": {
|
|
30
|
+
value += `${part.text}`
|
|
31
|
+
break
|
|
32
|
+
}
|
|
33
|
+
default: {
|
|
34
|
+
value += `${JSON.stringify(part, null, 2)}`
|
|
35
|
+
break
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
value += RESET
|
|
39
|
+
}
|
|
40
|
+
return value
|
|
41
|
+
}
|
package/reduce.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import { append } from "./append.ts"
|
|
3
|
+
import { clear } from "./clear.ts"
|
|
4
|
+
import { Strand } from "./Strand.ts"
|
|
5
|
+
import { strand } from "./strand_.ts"
|
|
6
|
+
|
|
7
|
+
/** Sequentially reduce the current strand's messages in chronological order. */
|
|
8
|
+
export const reduce: <E, R, E1, R1>(
|
|
9
|
+
reducer: Effect.Effect<Effect.Effect<void, E1, R1>, E, R>,
|
|
10
|
+
) => Effect.Effect<
|
|
11
|
+
void,
|
|
12
|
+
E | E1,
|
|
13
|
+
R | R1 | Strand
|
|
14
|
+
> = Effect.fnUntraced(function*(reducer) {
|
|
15
|
+
const parent = yield* Strand
|
|
16
|
+
if (!parent.messages.length || parent.messages.length === 1) return
|
|
17
|
+
const [m0, m1, ...mRest] = parent.messages
|
|
18
|
+
let acc = yield* strand(
|
|
19
|
+
append(m0!, m1!),
|
|
20
|
+
reducer,
|
|
21
|
+
)
|
|
22
|
+
while (mRest.length) {
|
|
23
|
+
acc = yield* strand(
|
|
24
|
+
acc,
|
|
25
|
+
append(mRest.pop()!),
|
|
26
|
+
reducer,
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
yield* clear
|
|
30
|
+
yield* acc
|
|
31
|
+
return
|
|
32
|
+
})
|
package/sequence_.ts
ADDED
package/strand_.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import { flow } from "effect/Function"
|
|
3
|
+
import * as Option from "effect/Option"
|
|
4
|
+
import * as PubSub from "effect/PubSub"
|
|
5
|
+
import type { LEvent } from "./LEvent.ts"
|
|
6
|
+
import { type Sequence } from "./Sequence.ts"
|
|
7
|
+
import { sequence } from "./sequence_.ts"
|
|
8
|
+
import { Strand } from "./Strand.ts"
|
|
9
|
+
|
|
10
|
+
/** Isolate the effect with a new strand in context. */
|
|
11
|
+
export const strand: Sequence<Strand> = flow(
|
|
12
|
+
sequence,
|
|
13
|
+
Effect.provideServiceEffect(
|
|
14
|
+
Strand,
|
|
15
|
+
Effect.gen(function*() {
|
|
16
|
+
return Strand.of({
|
|
17
|
+
parent: yield* Effect.serviceOption(Strand),
|
|
18
|
+
events: yield* PubSub.unbounded<LEvent>(),
|
|
19
|
+
system: Option.none(),
|
|
20
|
+
messages: [],
|
|
21
|
+
tools: [],
|
|
22
|
+
})
|
|
23
|
+
}),
|
|
24
|
+
),
|
|
25
|
+
)
|
package/system.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Option from "effect/Option"
|
|
3
|
+
import { normalize, type TaggableNullable } from "./internal/Taggable.ts"
|
|
4
|
+
import { Strand } from "./Strand.ts"
|
|
5
|
+
|
|
6
|
+
export const system: TaggableNullable<Effect.Effect<Option.Option<string>, never, Strand>> = Effect.fnUntraced(
|
|
7
|
+
function*(a0, ...aRest) {
|
|
8
|
+
const conversation = yield* Strand
|
|
9
|
+
const { system } = conversation
|
|
10
|
+
conversation.system = a0 ? Option.some(normalize(a0, aRest)) : Option.none()
|
|
11
|
+
return system
|
|
12
|
+
},
|
|
13
|
+
)
|
package/tsconfig.json
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
"extends": "../tsconfig.base",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"noEmit": false,
|
|
5
|
-
"outDir": "dist"
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "@effect/language-service",
|
|
9
|
+
"transform": "@effect/language-service/transform",
|
|
10
|
+
"namespaceImportPackages": ["effect", "@effect/ai"],
|
|
11
|
+
"diagnosticSeverity": {
|
|
12
|
+
"importFromBarrel": "error"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
]
|
|
6
16
|
},
|
|
7
17
|
"include": ["."]
|
|
8
18
|
}
|
package/user.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TextPart, UserMessage } from "@effect/ai/AiInput"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import { append } from "./append.ts"
|
|
4
|
+
import { normalize, type Taggable } from "./internal/Taggable.ts"
|
|
5
|
+
import * as Strand from "./Strand.ts"
|
|
6
|
+
|
|
7
|
+
/** Append a user message to the conversation. */
|
|
8
|
+
export const user: Taggable<Effect.Effect<void, never, Strand.Strand>> = (a0, ...aRest) =>
|
|
9
|
+
append(
|
|
10
|
+
UserMessage.make({
|
|
11
|
+
parts: [
|
|
12
|
+
TextPart.make({
|
|
13
|
+
text: normalize(a0, aRest),
|
|
14
|
+
}),
|
|
15
|
+
],
|
|
16
|
+
}),
|
|
17
|
+
)
|
package/userJson.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Schema from "effect/Schema"
|
|
3
|
+
import type { JsonValueObject } from "./internal/JsonValue.ts"
|
|
4
|
+
import * as Strand from "./Strand.ts"
|
|
5
|
+
import { user } from "./user.ts"
|
|
6
|
+
|
|
7
|
+
// TODO: serialize with comments from schema
|
|
8
|
+
/** Stringify and append some JSON as a user message to the conversation. */
|
|
9
|
+
export const userJson: <A, I extends JsonValueObject>(
|
|
10
|
+
value: A,
|
|
11
|
+
schema?: Schema.Schema<A, I, never>,
|
|
12
|
+
) => Effect.Effect<void, never, Strand.Strand> = (value) => user`\`\`\`jsonc\n${JSON.stringify(value, null, 2)}\n\`\`\``
|
package/dist/util/JSONValue.d.ts
DELETED
package/dist/util/JSONValue.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"JSONValue.js","sourceRoot":"","sources":["../../util/JSONValue.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare function fixTemplateStrings(template: TemplateStringsArray): {
|
|
2
|
-
readonly raw: readonly string[];
|
|
3
|
-
};
|
|
4
|
-
/**
|
|
5
|
-
* Applies template string indentation to substituted values with line breaks
|
|
6
|
-
*
|
|
7
|
-
* @param strings - The template strings array (processed through fixTemplateStrings)
|
|
8
|
-
* @param values - The substitution values
|
|
9
|
-
* @returns - The formatted string with properly indented substitutions
|
|
10
|
-
*/
|
|
11
|
-
export declare function applyTemplateWithIndentation(strings: TemplateStringsArray, ...values: any[]): string;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
const INDENTATION_RE = /^\n([ \t]+)/;
|
|
2
|
-
const ESCAPE_SEQ_RE = /\\([`${\\]|\n)/g;
|
|
3
|
-
const LAST_INDENTATION_RE = /\n[ \t]+$/;
|
|
4
|
-
export function fixTemplateStrings(template) {
|
|
5
|
-
const firstSegment = template.raw[0];
|
|
6
|
-
const leadingIndentMatch = INDENTATION_RE.exec(firstSegment);
|
|
7
|
-
const indentation = leadingIndentMatch?.[1];
|
|
8
|
-
const rawLength = template.raw.length;
|
|
9
|
-
const result = new Array(rawLength);
|
|
10
|
-
for (let i = 0; i < rawLength; i++) {
|
|
11
|
-
let str = template.raw[i];
|
|
12
|
-
// Only perform common indentation replacements if needed
|
|
13
|
-
if (indentation) {
|
|
14
|
-
// Remove leading newline and indentation in the first segment
|
|
15
|
-
if (i === 0) {
|
|
16
|
-
str = str.slice(indentation.length + 1);
|
|
17
|
-
}
|
|
18
|
-
// Use a simple string replacement with a regular expression for better performance
|
|
19
|
-
str = str.replaceAll(`\n${indentation}`, "\n");
|
|
20
|
-
}
|
|
21
|
-
// Replace common escape sequences in a single pass
|
|
22
|
-
str = str.replace(ESCAPE_SEQ_RE, (_match, char) => {
|
|
23
|
-
// Keep the escaped newline replacement separate for clarity
|
|
24
|
-
return char === "\n" ? "" : char;
|
|
25
|
-
});
|
|
26
|
-
// Handle trailing spaces only for the last segment
|
|
27
|
-
if (indentation && i === rawLength - 1) {
|
|
28
|
-
str = str.replace(LAST_INDENTATION_RE, "");
|
|
29
|
-
}
|
|
30
|
-
result[i] = str;
|
|
31
|
-
}
|
|
32
|
-
return { raw: result };
|
|
33
|
-
}
|
|
34
|
-
const LEADING_SPACE_RE = /^([ \t]*)/;
|
|
35
|
-
/**
|
|
36
|
-
* Applies template string indentation to substituted values with line breaks
|
|
37
|
-
*
|
|
38
|
-
* @param strings - The template strings array (processed through fixTemplateStrings)
|
|
39
|
-
* @param values - The substitution values
|
|
40
|
-
* @returns - The formatted string with properly indented substitutions
|
|
41
|
-
*/
|
|
42
|
-
export function applyTemplateWithIndentation(strings, ...values) {
|
|
43
|
-
const fixedStrings = fixTemplateStrings(strings);
|
|
44
|
-
const rawArr = fixedStrings.raw;
|
|
45
|
-
const valuesLength = values.length;
|
|
46
|
-
const resultParts = new Array(Math.max(1, rawArr.length * 2 - 1));
|
|
47
|
-
let resultIndex = 0;
|
|
48
|
-
for (let i = 0; i < rawArr.length; i++) {
|
|
49
|
-
const str = rawArr[i] || "";
|
|
50
|
-
resultParts[resultIndex++] = str;
|
|
51
|
-
// Only process values for non-final segments
|
|
52
|
-
if (i < valuesLength) {
|
|
53
|
-
const value = String(values[i]);
|
|
54
|
-
// If value has line breaks, we should indent it
|
|
55
|
-
if (value.includes("\n")) {
|
|
56
|
-
const lastNewlineIndex = str.lastIndexOf("\n");
|
|
57
|
-
if (lastNewlineIndex !== -1) {
|
|
58
|
-
// Extract the indentation after the last newline
|
|
59
|
-
const textAfterLastNewline = str.substring(lastNewlineIndex + 1);
|
|
60
|
-
const leadingSpaceMatch = LEADING_SPACE_RE.exec(textAfterLastNewline);
|
|
61
|
-
const indentationToApply = leadingSpaceMatch && leadingSpaceMatch[1] ? leadingSpaceMatch[1] : "";
|
|
62
|
-
if (indentationToApply) {
|
|
63
|
-
// Split the value into lines once
|
|
64
|
-
const lines = value.split("\n");
|
|
65
|
-
const linesLength = lines.length;
|
|
66
|
-
// First line doesn't need indentation
|
|
67
|
-
resultParts[resultIndex++] = lines[0];
|
|
68
|
-
// Apply indentation to subsequent lines
|
|
69
|
-
for (let j = 1; j < linesLength; j++) {
|
|
70
|
-
resultParts[resultIndex++] = "\n" + indentationToApply + lines[j];
|
|
71
|
-
}
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// For simple values or when no indentation is needed
|
|
77
|
-
resultParts[resultIndex++] = value;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Combine all parts at once
|
|
81
|
-
return resultParts.slice(0, resultIndex).join("");
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=fixTemplateStrings.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fixTemplateStrings.js","sourceRoot":"","sources":["../../util/fixTemplateStrings.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function isTemplateStringsArray(value: unknown): value is TemplateStringsArray;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isTemplateStringsArray.js","sourceRoot":"","sources":["../../util/isTemplateStringsArray.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AAC3E,CAAC"}
|
package/util/JSONValue.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
const INDENTATION_RE = /^\n([ \t]+)/
|
|
2
|
-
const ESCAPE_SEQ_RE = /\\([`${\\]|\n)/g
|
|
3
|
-
const LAST_INDENTATION_RE = /\n[ \t]+$/
|
|
4
|
-
|
|
5
|
-
export function fixTemplateStrings(template: TemplateStringsArray): { readonly raw: readonly string[] } {
|
|
6
|
-
const firstSegment = template.raw[0]!
|
|
7
|
-
const leadingIndentMatch = INDENTATION_RE.exec(firstSegment)
|
|
8
|
-
const indentation = leadingIndentMatch?.[1]
|
|
9
|
-
|
|
10
|
-
const rawLength = template.raw.length
|
|
11
|
-
const result = new Array(rawLength)
|
|
12
|
-
|
|
13
|
-
for (let i = 0; i < rawLength; i++) {
|
|
14
|
-
let str = template.raw[i]!
|
|
15
|
-
// Only perform common indentation replacements if needed
|
|
16
|
-
if (indentation) {
|
|
17
|
-
// Remove leading newline and indentation in the first segment
|
|
18
|
-
if (i === 0) {
|
|
19
|
-
str = str.slice(indentation.length + 1)
|
|
20
|
-
}
|
|
21
|
-
// Use a simple string replacement with a regular expression for better performance
|
|
22
|
-
str = str.replaceAll(`\n${indentation}`, "\n")
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Replace common escape sequences in a single pass
|
|
26
|
-
str = str.replace(ESCAPE_SEQ_RE, (_match, char) => {
|
|
27
|
-
// Keep the escaped newline replacement separate for clarity
|
|
28
|
-
return char === "\n" ? "" : char
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// Handle trailing spaces only for the last segment
|
|
32
|
-
if (indentation && i === rawLength - 1) {
|
|
33
|
-
str = str.replace(LAST_INDENTATION_RE, "")
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
result[i] = str
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return { raw: result }
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const LEADING_SPACE_RE = /^([ \t]*)/
|
|
43
|
-
/**
|
|
44
|
-
* Applies template string indentation to substituted values with line breaks
|
|
45
|
-
*
|
|
46
|
-
* @param strings - The template strings array (processed through fixTemplateStrings)
|
|
47
|
-
* @param values - The substitution values
|
|
48
|
-
* @returns - The formatted string with properly indented substitutions
|
|
49
|
-
*/
|
|
50
|
-
export function applyTemplateWithIndentation(strings: TemplateStringsArray, ...values: any[]): string {
|
|
51
|
-
const fixedStrings = fixTemplateStrings(strings)
|
|
52
|
-
const rawArr = fixedStrings.raw
|
|
53
|
-
const valuesLength = values.length
|
|
54
|
-
|
|
55
|
-
const resultParts = new Array(Math.max(1, rawArr.length * 2 - 1))
|
|
56
|
-
let resultIndex = 0
|
|
57
|
-
|
|
58
|
-
for (let i = 0; i < rawArr.length; i++) {
|
|
59
|
-
const str = rawArr[i] || ""
|
|
60
|
-
resultParts[resultIndex++] = str
|
|
61
|
-
|
|
62
|
-
// Only process values for non-final segments
|
|
63
|
-
if (i < valuesLength) {
|
|
64
|
-
const value = String(values[i])
|
|
65
|
-
|
|
66
|
-
// If value has line breaks, we should indent it
|
|
67
|
-
if (value.includes("\n")) {
|
|
68
|
-
const lastNewlineIndex = str.lastIndexOf("\n")
|
|
69
|
-
|
|
70
|
-
if (lastNewlineIndex !== -1) {
|
|
71
|
-
// Extract the indentation after the last newline
|
|
72
|
-
const textAfterLastNewline = str.substring(lastNewlineIndex + 1)
|
|
73
|
-
const leadingSpaceMatch = LEADING_SPACE_RE.exec(textAfterLastNewline)
|
|
74
|
-
const indentationToApply = leadingSpaceMatch && leadingSpaceMatch[1] ? leadingSpaceMatch[1] : ""
|
|
75
|
-
|
|
76
|
-
if (indentationToApply) {
|
|
77
|
-
// Split the value into lines once
|
|
78
|
-
const lines = value.split("\n")
|
|
79
|
-
const linesLength = lines.length
|
|
80
|
-
|
|
81
|
-
// First line doesn't need indentation
|
|
82
|
-
resultParts[resultIndex++] = lines[0]
|
|
83
|
-
|
|
84
|
-
// Apply indentation to subsequent lines
|
|
85
|
-
for (let j = 1; j < linesLength; j++) {
|
|
86
|
-
resultParts[resultIndex++] = "\n" + indentationToApply + lines[j]
|
|
87
|
-
}
|
|
88
|
-
continue
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
// For simple values or when no indentation is needed
|
|
93
|
-
resultParts[resultIndex++] = value
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Combine all parts at once
|
|
98
|
-
return resultParts.slice(0, resultIndex).join("")
|
|
99
|
-
}
|