liminal 0.5.6 → 0.5.8

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/Agent.ts CHANGED
@@ -5,10 +5,9 @@ import { MessageRegistry, MessageRegistryContext } from "./MessageRegistry.ts"
5
5
  import { ModelRegistry, ModelRegistryContext } from "./ModelRegistry.ts"
6
6
  import type { Rune } from "./Rune.ts"
7
7
  import type { Runic } from "./Runic.ts"
8
- import type { RuntimeEvent } from "./RuntimeEvent.ts"
9
8
 
10
- export interface AgentConfig<E> {
11
- handler?: ((event: RuntimeEvent<E>) => void) | undefined
9
+ export interface AgentConfig<T, E> {
10
+ handler?: ((this: Fiber<T>, event: E) => void) | undefined
12
11
  models?: ModelRegistry
13
12
  messages?: MessageRegistry
14
13
  signal?: AbortSignal | undefined
@@ -21,16 +20,16 @@ export interface Agent<out T, out E> extends PromiseLike<T> {
21
20
 
22
21
  export function Agent<Y extends Rune, T>(
23
22
  runic: Runic<Y, T>,
24
- config?: AgentConfig<Rune.E<Y>>,
23
+ config?: AgentConfig<T, Rune.E<Y>>,
25
24
  ): Agent<T, Rune.E<Y>> {
26
25
  return {
27
26
  then(onfulfilled, onrejected) {
28
- const rootCtx = new Context([
27
+ return new Context([
29
28
  [HandlerContext, config?.handler],
30
29
  [ModelRegistryContext, config?.models ?? new ModelRegistry()],
31
30
  [MessageRegistryContext, config?.messages ?? new MessageRegistry()],
32
31
  ])
33
- return rootCtx.run(() => Fiber(runic).resolve().then(onfulfilled, onrejected))
32
+ .run(() => new Fiber(runic).resolution().then(onfulfilled, onrejected))
34
33
  },
35
34
  } satisfies Omit<Agent<T, Rune.E<Y>>, "E" | "T"> as never
36
35
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # liminal
2
2
 
3
+ ## 0.5.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 23a24ae: Reintroduce L.catch and clean up parts of the generator runtime.
8
+ - f2f360c: Continue to clean up the generator runtime internals.
9
+ - Updated dependencies [23a24ae]
10
+ - Updated dependencies [f2f360c]
11
+ - liminal-schema@0.0.3
12
+ - liminal-util@0.0.4
13
+
14
+ ## 0.5.7
15
+
16
+ ### Patch Changes
17
+
18
+ - a56f121: Re-flatten events. Make fiber info available in event handler via this.
19
+ - Updated dependencies [a56f121]
20
+ - liminal-util@0.0.3
21
+
3
22
  ## 0.5.6
4
23
 
5
24
  ### Patch Changes
package/EventBase.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { inspect, type InspectOptions } from "node:util"
1
+ import { attachCustomInspect } from "liminal-util"
2
2
 
3
3
  export interface EventBase<B extends symbol = symbol, K extends string = string> {
4
4
  readonly brand: B
@@ -10,17 +10,8 @@ export function EventBase<B extends symbol, K extends string>(brand: B, type: K)
10
10
  readonly brand = brand
11
11
  readonly type = type
12
12
 
13
- // Allows us to circumvent a false positive ts error related to private symbols.
14
- // https://github.com/microsoft/TypeScript/issues/58496
15
13
  static {
16
- Object.defineProperties(this.prototype, {
17
- [inspect.custom]: {
18
- value(depth: number, options: InspectOptions) {
19
- const { brand: _0, type: _1, ...rest } = this
20
- return `${this.constructor.name} ` + inspect(rest, { ...options, depth })
21
- },
22
- },
23
- })
14
+ attachCustomInspect(this, ({ brand: _0, type: _1, ...rest }) => rest)
24
15
  }
25
16
  }
26
17
  }
package/Fiber.ts CHANGED
@@ -1,54 +1,105 @@
1
+ import { attachCustomInspect } from "liminal-util"
1
2
  import { Context } from "./Context.ts"
2
3
  import type { Rune } from "./Rune.ts"
3
4
  import { Runic } from "./Runic.ts"
4
5
 
5
- export interface FiberInfo {
6
- readonly index: number
7
- readonly parent?: FiberInfo
6
+ export type FiberStatus<T> = {
7
+ type: "untouched"
8
+ } | {
9
+ type: "pending"
10
+ self: AbortSignal
11
+ promise: Promise<T>
12
+ } | {
13
+ type: "aborted"
14
+ reason: unknown
15
+ } | {
16
+ type: "resolved"
17
+ value: T
18
+ } | {
19
+ type: "rejected"
20
+ exception: unknown
8
21
  }
9
22
 
10
- let nextIndex = 0
23
+ export class Fiber<T = any> {
24
+ static nextIndex: number = 0
11
25
 
12
- export interface Fiber<T = any> {
13
- parent?: Fiber | undefined
14
- info: FiberInfo
15
- resolve(): Promise<T>
16
- }
26
+ declare T: T
27
+ readonly index: number = Fiber.nextIndex++
28
+
29
+ #runic: Runic<Rune, T>
30
+ declare readonly parent?: Fiber
31
+ #context: Context = Context.ensure()
32
+
33
+ signal: AbortSignal
34
+ either: AbortSignal
35
+ abort: (reason?: any) => void
17
36
 
18
- export function Fiber<T = any>(runic: Runic<Rune, T>, parent?: Fiber): Fiber<T> {
19
- let index = nextIndex++
20
- let pending: Promise<T> | undefined
21
- const context = Context.ensure()
22
- return {
23
- parent,
24
- info: {
25
- index,
26
- ...parent && { parent: parent.info },
27
- },
28
- resolve,
37
+ status: FiberStatus<T> = { type: "untouched" }
38
+
39
+ constructor(runic: Runic<Rune, T>, parent?: Fiber) {
40
+ this.#runic = runic
41
+ if (parent) {
42
+ this.parent = parent
43
+ }
44
+ const controller = new AbortController()
45
+ this.signal = controller.signal
46
+ this.either = AbortSignal.any([
47
+ ...this.parent?.signal ? [this.parent.signal] : [],
48
+ this.signal,
49
+ ])
50
+ this.abort = controller.abort.bind(controller)
29
51
  }
30
52
 
31
- function resolve(this: Fiber<T>): Promise<T> {
32
- if (!pending) {
33
- const { promise, resolve, reject } = Promise.withResolvers<T>()
34
- pending = promise
35
- const iterator = Runic.unwrap(runic)
36
- let nextArg: unknown
37
- context.run(async () => {
38
- try {
39
- let current = await iterator.next()
40
- while (!current.done) {
41
- const rune = current.value
42
- nextArg = await rune(this)
43
- current = await iterator.next(nextArg)
44
- }
45
- const { value } = current
46
- resolve(value)
47
- } catch (error) {
48
- reject(error)
53
+ static async join<F extends Array<Fiber>>(fibers: F): Promise<{ [I in keyof F]: F[I]["T"] }> {
54
+ return await Promise.all(fibers.map((fiber) => fiber.resolution())) as never
55
+ }
56
+
57
+ resolution(this: Fiber<T>): Promise<T> {
58
+ const { status, abort } = this
59
+ switch (status.type) {
60
+ case "untouched": {
61
+ const { promise, resolve, reject } = Promise.withResolvers<T>()
62
+ this.status = {
63
+ type: "pending",
64
+ self: this.signal,
65
+ promise,
49
66
  }
50
- })
67
+ const iterator = Runic.unwrap(this.#runic)
68
+ let nextArg: unknown
69
+ this.#context.run(async () => {
70
+ try {
71
+ let current = await iterator.next()
72
+ while (!current.done) {
73
+ const rune = current.value
74
+ nextArg = await rune(this)
75
+ current = await iterator.next(nextArg)
76
+ }
77
+ const { value } = current
78
+ abort()
79
+ resolve(value)
80
+ } catch (exception) {
81
+ abort(exception)
82
+ reject(exception)
83
+ }
84
+ })
85
+ return promise
86
+ }
87
+ case "pending": {
88
+ return status.promise
89
+ }
90
+ case "resolved": {
91
+ return Promise.resolve(status.value)
92
+ }
93
+ case "rejected": {
94
+ return Promise.reject(status.exception)
95
+ }
96
+ case "aborted": {
97
+ return Promise.reject(status.reason)
98
+ }
51
99
  }
52
- return pending
100
+ }
101
+
102
+ static {
103
+ attachCustomInspect(this, ({ index, parent }) => ({ index, ...parent && { parent } }))
53
104
  }
54
105
  }
package/Handler.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ContextHandle } from "./Context.ts"
2
- import type { RuntimeEvent } from "./RuntimeEvent.ts"
2
+ import type { Fiber } from "./Fiber.ts"
3
3
 
4
- export type Handler<E = any> = [(event: RuntimeEvent<E>) => void][0]
4
+ export type Handler<E = any> = [(this: Fiber, event: E) => void][0]
5
5
 
6
6
  export const HandlerContext: ContextHandle<Handler | undefined> = ContextHandle()
package/L/L.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./_infer.ts"
3
3
  export * from "./_message.ts"
4
4
  export * from "./assistant.ts"
5
5
  export * from "./branch.ts"
6
+ export * from "./catch.ts"
6
7
  export * from "./emit.ts"
7
8
  export * from "./model.ts"
8
9
  export * from "./system.ts"
package/L/assistant.ts CHANGED
@@ -6,7 +6,7 @@ import { _message } from "./_message.ts"
6
6
  import { rune } from "./rune.ts"
7
7
 
8
8
  export interface assistant extends Iterable<Rune<LEvent>, string> {
9
- <T>(schema: LType<T>): Generator<Rune<LEvent>, T>
9
+ <T>(type: LType<T>): Generator<Rune<LEvent>, T>
10
10
  }
11
11
 
12
12
  export const assistant: assistant = Object.assign(
package/L/branch.ts CHANGED
@@ -17,17 +17,20 @@ export function* branch(value: Runic | Array<Runic> | Record<keyof any, Runic>):
17
17
  const context = Context.ensure()
18
18
  const parent = yield* rune((fiber) => fiber)
19
19
  if (Array.isArray(value)) {
20
- const fibers = value.map((runic) => context.clone().run(() => Fiber(runic, parent)))
21
- return yield* rune(() => Promise.all(fibers.map(({ resolve }) => resolve())))
20
+ const fibers = value.map((runic) => context.clone().run(() => new Fiber(runic, parent)))
21
+ return yield* rune(() => Fiber.join(fibers))
22
22
  } else if (typeof value === "object") {
23
- const entries = Object.entries(value)
24
- const fibers = entries.map(([_key, runic]) => context.clone().run(() => Fiber(runic, parent)))
25
- return yield* rune(() =>
26
- Promise
27
- .all(fibers.map(({ resolve }, i) => resolve().then((value) => [entries[i]![0], value])))
28
- .then(Object.fromEntries)
23
+ const fibers = Object.values(value).map(
24
+ (runic) => context.clone().run(() => new Fiber(runic, parent)),
29
25
  )
26
+ return yield* rune(async () => {
27
+ const keys = Object.keys(value)
28
+ return await Fiber
29
+ .join(fibers)
30
+ .then((resolved) => resolved.map((value, i) => [keys[i], value]))
31
+ .then(Object.fromEntries)
32
+ })
30
33
  }
31
- const fiber = context.clone().run(() => Fiber(typeof value === "function" ? value() : value, parent))
32
- return yield* rune(() => fiber.resolve())
34
+ const fiber = context.clone().run(() => new Fiber(typeof value === "function" ? value() : value, parent))
35
+ return yield* rune(() => fiber.resolution())
33
36
  }
package/L/catch.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { Fiber } from "../Fiber.ts"
2
+ import type { Rune } from "../Rune.ts"
3
+ import type { Runic } from "../Runic.ts"
4
+ import { rune } from "./rune.ts"
5
+
6
+ export { catch_ as catch }
7
+ function* catch_<Y extends Rune, T>(runic: Runic<Y, T>): Generator<Rune<Y>, CatchResult<T>> {
8
+ return yield* rune(async () => {
9
+ try {
10
+ return { resolved: await new Fiber(runic).resolution() }
11
+ } catch (exception: unknown) {
12
+ return { rejected: exception }
13
+ }
14
+ })
15
+ }
16
+ Object.defineProperty(catch_, "name", { value: "catch" })
17
+
18
+ export type CatchResult<T> = {
19
+ resolved: T
20
+ rejected?: never
21
+ } | {
22
+ resolved?: never
23
+ rejected: unknown
24
+ }
package/L/emit.ts CHANGED
@@ -10,9 +10,5 @@ export function* emit<const E>(event: EnsureNarrow<E>): emit<E> {
10
10
  const context = Context.ensure()
11
11
  const handler = context.get(HandlerContext)
12
12
  const fiber = yield* rune((fiber) => fiber)
13
- handler?.({
14
- ...fiber.info,
15
- ...fiber.parent && { parent: fiber.parent.info },
16
- event,
17
- })
13
+ handler?.call(fiber, event)
18
14
  }
package/L/rune.ts CHANGED
@@ -8,11 +8,11 @@ export interface rune<T> extends Iterable<Rune<never>, T> {
8
8
  export function rune<R>(source: (fiber: Fiber) => R): rune<Awaited<R>> {
9
9
  return Object.assign(
10
10
  function*<E>(): Generator<Rune<E>, Awaited<R>> {
11
- return yield Object.assign(source, { [RuneKey]: {} as never })
11
+ return yield Object.assign(source, { [RuneKey]: true } as never)
12
12
  },
13
13
  {
14
14
  *[Symbol.iterator](): Generator<Rune<never>, Awaited<R>> {
15
- return yield Object.assign(source, { [RuneKey]: {} as never })
15
+ return yield Object.assign(source, { [RuneKey]: true } as never)
16
16
  },
17
17
  },
18
18
  )
package/Model.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import type { Schema } from "liminal-schema"
2
+ import { attachCustomInspect } from "liminal-util"
2
3
  import type { Message } from "./Message.ts"
3
4
 
4
- export interface Model {
5
- resolve(messages: Array<Message>, schema?: Schema): Promise<string>
6
- }
5
+ export class Model {
6
+ constructor(
7
+ readonly vendor: string,
8
+ readonly resolve: (messages: Array<Message>, schema?: Schema) => Promise<string>,
9
+ ) {}
7
10
 
8
- // export interface ModelCapabilities {
9
- // readonly url: boolean
10
- // readonly mimes: Set<string>
11
- // readonly reasoning: boolean
12
- // readonly structures: boolean
13
- // }
11
+ static {
12
+ attachCustomInspect(this, ({ vendor }) => ({ vendor }))
13
+ }
14
+ }
package/Rune.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import type { Fiber } from "./Fiber.ts"
2
2
 
3
3
  export interface Rune<out E = any> {
4
+ E: E
4
5
  (fiber: Fiber): any
5
- [RuneKey]: E
6
+ [RuneKey]: true
6
7
  }
7
8
 
8
9
  export declare namespace Rune {
9
- export type E<X extends Rune> = X[RuneKey]
10
+ export type E<X extends Rune> = X["E"]
10
11
  }
11
12
 
12
13
  export const RuneKey: unique symbol = Symbol.for("liminal/Rune")
package/dist/Agent.d.ts CHANGED
@@ -1,10 +1,10 @@
1
+ import { Fiber } from "./Fiber.ts";
1
2
  import { MessageRegistry } from "./MessageRegistry.ts";
2
3
  import { ModelRegistry } from "./ModelRegistry.ts";
3
4
  import type { Rune } from "./Rune.ts";
4
5
  import type { Runic } from "./Runic.ts";
5
- import type { RuntimeEvent } from "./RuntimeEvent.ts";
6
- export interface AgentConfig<E> {
7
- handler?: ((event: RuntimeEvent<E>) => void) | undefined;
6
+ export interface AgentConfig<T, E> {
7
+ handler?: ((this: Fiber<T>, event: E) => void) | undefined;
8
8
  models?: ModelRegistry;
9
9
  messages?: MessageRegistry;
10
10
  signal?: AbortSignal | undefined;
@@ -13,4 +13,4 @@ export interface Agent<out T, out E> extends PromiseLike<T> {
13
13
  T: T;
14
14
  E: E;
15
15
  }
16
- export declare function Agent<Y extends Rune, T>(runic: Runic<Y, T>, config?: AgentConfig<Rune.E<Y>>): Agent<T, Rune.E<Y>>;
16
+ export declare function Agent<Y extends Rune, T>(runic: Runic<Y, T>, config?: AgentConfig<T, Rune.E<Y>>): Agent<T, Rune.E<Y>>;
package/dist/Agent.js CHANGED
@@ -6,12 +6,12 @@ import { ModelRegistry, ModelRegistryContext } from "./ModelRegistry.js";
6
6
  export function Agent(runic, config) {
7
7
  return {
8
8
  then(onfulfilled, onrejected) {
9
- const rootCtx = new Context([
9
+ return new Context([
10
10
  [HandlerContext, config?.handler],
11
11
  [ModelRegistryContext, config?.models ?? new ModelRegistry()],
12
12
  [MessageRegistryContext, config?.messages ?? new MessageRegistry()],
13
- ]);
14
- return rootCtx.run(() => Fiber(runic).resolve().then(onfulfilled, onrejected));
13
+ ])
14
+ .run(() => new Fiber(runic).resolution().then(onfulfilled, onrejected));
15
15
  },
16
16
  };
17
17
  }
package/dist/Agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Agent.js","sourceRoot":"","sources":["../Agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAiBxE,MAAM,UAAU,KAAK,CACnB,KAAkB,EAClB,MAA+B;IAE/B,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,UAAU;YAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC1B,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;gBACjC,CAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC7D,CAAC,sBAAsB,EAAE,MAAM,EAAE,QAAQ,IAAI,IAAI,eAAe,EAAE,CAAC;aACpE,CAAC,CAAA;YACF,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;QAChF,CAAC;KACsD,CAAA;AAC3D,CAAC"}
1
+ {"version":3,"file":"Agent.js","sourceRoot":"","sources":["../Agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAgBxE,MAAM,UAAU,KAAK,CACnB,KAAkB,EAClB,MAAkC;IAElC,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,UAAU;YAC1B,OAAO,IAAI,OAAO,CAAC;gBACjB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC;gBACjC,CAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC7D,CAAC,sBAAsB,EAAE,MAAM,EAAE,QAAQ,IAAI,IAAI,eAAe,EAAE,CAAC;aACpE,CAAC;iBACC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;QAC3E,CAAC;KACsD,CAAA;AAC3D,CAAC"}
package/dist/EventBase.js CHANGED
@@ -1,19 +1,10 @@
1
- import { inspect } from "node:util";
1
+ import { attachCustomInspect } from "liminal-util";
2
2
  export function EventBase(brand, type) {
3
3
  return class {
4
4
  brand = brand;
5
5
  type = type;
6
- // Allows us to circumvent a false positive ts error related to private symbols.
7
- // https://github.com/microsoft/TypeScript/issues/58496
8
6
  static {
9
- Object.defineProperties(this.prototype, {
10
- [inspect.custom]: {
11
- value(depth, options) {
12
- const { brand: _0, type: _1, ...rest } = this;
13
- return `${this.constructor.name} ` + inspect(rest, { ...options, depth });
14
- },
15
- },
16
- });
7
+ attachCustomInspect(this, ({ brand: _0, type: _1, ...rest }) => rest);
17
8
  }
18
9
  };
19
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EventBase.js","sourceRoot":"","sources":["../EventBase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,WAAW,CAAA;AAOxD,MAAM,UAAU,SAAS,CAAqC,KAAQ,EAAE,IAAO;IAC7E,OAAO;QACI,KAAK,GAAG,KAAK,CAAA;QACb,IAAI,GAAG,IAAI,CAAA;QAEpB,gFAAgF;QAChF,uDAAuD;QACvD;YACE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE;gBACtC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBAChB,KAAK,CAAC,KAAa,EAAE,OAAuB;wBAC1C,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;wBAC7C,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;oBAC3E,CAAC;iBACF;aACF,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"EventBase.js","sourceRoot":"","sources":["../EventBase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAOlD,MAAM,UAAU,SAAS,CAAqC,KAAQ,EAAE,IAAO;IAC7E,OAAO;QACI,KAAK,GAAG,KAAK,CAAA;QACb,IAAI,GAAG,IAAI,CAAA;QAEpB;YACE,mBAAmB,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAA;QACvE,CAAC;KACF,CAAA;AACH,CAAC"}
package/dist/Fiber.d.ts CHANGED
@@ -1,12 +1,34 @@
1
1
  import type { Rune } from "./Rune.ts";
2
2
  import { Runic } from "./Runic.ts";
3
- export interface FiberInfo {
3
+ export type FiberStatus<T> = {
4
+ type: "untouched";
5
+ } | {
6
+ type: "pending";
7
+ self: AbortSignal;
8
+ promise: Promise<T>;
9
+ } | {
10
+ type: "aborted";
11
+ reason: unknown;
12
+ } | {
13
+ type: "resolved";
14
+ value: T;
15
+ } | {
16
+ type: "rejected";
17
+ exception: unknown;
18
+ };
19
+ export declare class Fiber<T = any> {
20
+ #private;
21
+ static nextIndex: number;
22
+ T: T;
4
23
  readonly index: number;
5
- readonly parent?: FiberInfo;
24
+ readonly parent?: Fiber;
25
+ signal: AbortSignal;
26
+ either: AbortSignal;
27
+ abort: (reason?: any) => void;
28
+ status: FiberStatus<T>;
29
+ constructor(runic: Runic<Rune, T>, parent?: Fiber);
30
+ static join<F extends Array<Fiber>>(fibers: F): Promise<{
31
+ [I in keyof F]: F[I]["T"];
32
+ }>;
33
+ resolution(this: Fiber<T>): Promise<T>;
6
34
  }
7
- export interface Fiber<T = any> {
8
- parent?: Fiber | undefined;
9
- info: FiberInfo;
10
- resolve(): Promise<T>;
11
- }
12
- export declare function Fiber<T = any>(runic: Runic<Rune, T>, parent?: Fiber): Fiber<T>;
package/dist/Fiber.js CHANGED
@@ -1,41 +1,78 @@
1
+ import { attachCustomInspect } from "liminal-util";
1
2
  import { Context } from "./Context.js";
2
3
  import { Runic } from "./Runic.js";
3
- let nextIndex = 0;
4
- export function Fiber(runic, parent) {
5
- let index = nextIndex++;
6
- let pending;
7
- const context = Context.ensure();
8
- return {
9
- parent,
10
- info: {
11
- index,
12
- ...parent && { parent: parent.info },
13
- },
14
- resolve,
15
- };
16
- function resolve() {
17
- if (!pending) {
18
- const { promise, resolve, reject } = Promise.withResolvers();
19
- pending = promise;
20
- const iterator = Runic.unwrap(runic);
21
- let nextArg;
22
- context.run(async () => {
23
- try {
24
- let current = await iterator.next();
25
- while (!current.done) {
26
- const rune = current.value;
27
- nextArg = await rune(this);
28
- current = await iterator.next(nextArg);
4
+ export class Fiber {
5
+ static nextIndex = 0;
6
+ index = Fiber.nextIndex++;
7
+ #runic;
8
+ #context = Context.ensure();
9
+ signal;
10
+ either;
11
+ abort;
12
+ status = { type: "untouched" };
13
+ constructor(runic, parent) {
14
+ this.#runic = runic;
15
+ if (parent) {
16
+ this.parent = parent;
17
+ }
18
+ const controller = new AbortController();
19
+ this.signal = controller.signal;
20
+ this.either = AbortSignal.any([
21
+ ...this.parent?.signal ? [this.parent.signal] : [],
22
+ this.signal,
23
+ ]);
24
+ this.abort = controller.abort.bind(controller);
25
+ }
26
+ static async join(fibers) {
27
+ return await Promise.all(fibers.map((fiber) => fiber.resolution()));
28
+ }
29
+ resolution() {
30
+ const { status, abort } = this;
31
+ switch (status.type) {
32
+ case "untouched": {
33
+ const { promise, resolve, reject } = Promise.withResolvers();
34
+ this.status = {
35
+ type: "pending",
36
+ self: this.signal,
37
+ promise,
38
+ };
39
+ const iterator = Runic.unwrap(this.#runic);
40
+ let nextArg;
41
+ this.#context.run(async () => {
42
+ try {
43
+ let current = await iterator.next();
44
+ while (!current.done) {
45
+ const rune = current.value;
46
+ nextArg = await rune(this);
47
+ current = await iterator.next(nextArg);
48
+ }
49
+ const { value } = current;
50
+ abort();
51
+ resolve(value);
29
52
  }
30
- const { value } = current;
31
- resolve(value);
32
- }
33
- catch (error) {
34
- reject(error);
35
- }
36
- });
53
+ catch (exception) {
54
+ abort(exception);
55
+ reject(exception);
56
+ }
57
+ });
58
+ return promise;
59
+ }
60
+ case "pending": {
61
+ return status.promise;
62
+ }
63
+ case "resolved": {
64
+ return Promise.resolve(status.value);
65
+ }
66
+ case "rejected": {
67
+ return Promise.reject(status.exception);
68
+ }
69
+ case "aborted": {
70
+ return Promise.reject(status.reason);
71
+ }
37
72
  }
38
- return pending;
73
+ }
74
+ static {
75
+ attachCustomInspect(this, ({ index, parent }) => ({ index, ...parent && { parent } }));
39
76
  }
40
77
  }
41
78
  //# sourceMappingURL=Fiber.js.map
package/dist/Fiber.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Fiber.js","sourceRoot":"","sources":["../Fiber.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAOlC,IAAI,SAAS,GAAG,CAAC,CAAA;AAQjB,MAAM,UAAU,KAAK,CAAU,KAAqB,EAAE,MAAc;IAClE,IAAI,KAAK,GAAG,SAAS,EAAE,CAAA;IACvB,IAAI,OAA+B,CAAA;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAA;IAChC,OAAO;QACL,MAAM;QACN,IAAI,EAAE;YACJ,KAAK;YACL,GAAG,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;SACrC;QACD,OAAO;KACR,CAAA;IAED,SAAS,OAAO;QACd,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAK,CAAA;YAC/D,OAAO,GAAG,OAAO,CAAA;YACjB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACpC,IAAI,OAAgB,CAAA;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;gBACrB,IAAI,CAAC;oBACH,IAAI,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;oBACnC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;wBACrB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAA;wBAC1B,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;wBAC1B,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;oBACxC,CAAC;oBACD,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;oBACzB,OAAO,CAAC,KAAK,CAAC,CAAA;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,CAAA;gBACf,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"Fiber.js","sourceRoot":"","sources":["../Fiber.ts"],"names":[],"mappings":"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"}
package/dist/Handler.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { ContextHandle } from "./Context.ts";
2
- import type { RuntimeEvent } from "./RuntimeEvent.ts";
3
- export type Handler<E = any> = [(event: RuntimeEvent<E>) => void][0];
2
+ import type { Fiber } from "./Fiber.ts";
3
+ export type Handler<E = any> = [(this: Fiber, event: E) => void][0];
4
4
  export declare const HandlerContext: ContextHandle<Handler | undefined>;
package/dist/L/L.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./_infer.ts";
3
3
  export * from "./_message.ts";
4
4
  export * from "./assistant.ts";
5
5
  export * from "./branch.ts";
6
+ export * from "./catch.ts";
6
7
  export * from "./emit.ts";
7
8
  export * from "./model.ts";
8
9
  export * from "./system.ts";