tyneq 1.0.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/LICENSE +21 -0
- package/README.md +319 -0
- package/dist/Lazy.cjs +762 -0
- package/dist/Lazy.cjs.map +1 -0
- package/dist/Lazy.js +691 -0
- package/dist/Lazy.js.map +1 -0
- package/dist/TyneqCachedTerminalOperator.cjs +4950 -0
- package/dist/TyneqCachedTerminalOperator.cjs.map +1 -0
- package/dist/TyneqCachedTerminalOperator.d.cts +724 -0
- package/dist/TyneqCachedTerminalOperator.d.cts.map +1 -0
- package/dist/TyneqCachedTerminalOperator.d.ts +724 -0
- package/dist/TyneqCachedTerminalOperator.d.ts.map +1 -0
- package/dist/TyneqCachedTerminalOperator.js +4741 -0
- package/dist/TyneqCachedTerminalOperator.js.map +1 -0
- package/dist/ValidationBuilder.cjs +80 -0
- package/dist/ValidationBuilder.cjs.map +1 -0
- package/dist/ValidationBuilder.d.cts +319 -0
- package/dist/ValidationBuilder.d.cts.map +1 -0
- package/dist/ValidationBuilder.d.ts +319 -0
- package/dist/ValidationBuilder.d.ts.map +1 -0
- package/dist/ValidationBuilder.js +69 -0
- package/dist/ValidationBuilder.js.map +1 -0
- package/dist/core.d.cts +1393 -0
- package/dist/core.d.cts.map +1 -0
- package/dist/core.d.ts +1393 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/index.cjs +863 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1038 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +1038 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +809 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/index.cjs +24 -0
- package/dist/plugin/index.d.cts +89 -0
- package/dist/plugin/index.d.cts.map +1 -0
- package/dist/plugin/index.d.ts +89 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +2 -0
- package/dist/utility/index.cjs +9 -0
- package/dist/utility/index.d.cts +2 -0
- package/dist/utility/index.d.ts +2 -0
- package/dist/utility/index.js +3 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/core/generators/range.ts","../src/core/generators/random.ts","../src/core/EnumerableAdapter.ts","../src/core/generators/repeat.ts","../src/core/generators/generate.ts","../src/core/generators/sourceConcat.ts","../src/core/tyneq.ts","../src/core/errors/KeyNotFoundError.ts","../src/core/errors/NotSupportedError.ts","../src/core/errors/CompilerError.ts","../src/queryplan/QueryPlanPrinter.ts","../src/queryplan/QueryPlanWalker.ts","../src/queryplan/QueryPlanTransformer.ts","../src/queryplan/QueryPlanOptimizer.ts","../src/queryplan/compiler/QueryPlanCompiler.ts"],"sourcesContent":["import { TyneqBaseEnumerator } from \"../enumerators/TyneqBaseEnumerator\";\r\n\r\nexport class RangeEnumerator extends TyneqBaseEnumerator<number> {\r\n private current: number;\r\n private end: number;\r\n\r\n public constructor(start: number, end: number) {\r\n super();\r\n this.current = start;\r\n this.end = end;\r\n }\r\n\r\n protected override handleNext(): IteratorResult<number> {\r\n if (this.current > this.end) {\r\n return this.done();\r\n }\r\n\r\n return this.yield(this.current++);\r\n }\r\n}\r\n","import { TyneqBaseEnumerator } from \"../enumerators/TyneqBaseEnumerator\";\r\n\r\nexport class RandomEnumerator<TSource> extends TyneqBaseEnumerator<TSource> {\r\n private readonly count: number;\r\n private readonly randomizer: () => TSource;\r\n\r\n private yieldedCount: number = 0;\r\n\r\n \r\n public constructor(count: number, randomizer: () => TSource) {\r\n super();\r\n this.count = count;\r\n this.randomizer = randomizer;\r\n }\r\n\r\n protected override handleNext(): IteratorResult<TSource> {\r\n if (this.yieldedCount >= this.count) {\r\n return this.done();\r\n }\r\n\r\n this.yieldedCount++;\r\n return this.yield(this.randomizer());\r\n }\r\n}\r\n","import { Enumerable, Enumerator } from \"../types/core\";\r\nimport { ArgumentUtility } from \"../utility/ArgumentUtility\";\r\n\r\n/**\r\n * Wraps a native `Iterable<T>` as a Tyneq {@link Enumerable}.\r\n *\r\n * @remarks\r\n * Used by `Tyneq.from()` to adapt arrays, sets, generators, and any other iterable.\r\n * Each call to `getEnumerator()` delegates to the underlying `[Symbol.iterator]()`.\r\n *\r\n * @internal\r\n */\r\nexport class EnumerableAdapter<TSource> implements Enumerable<TSource> {\r\n private readonly iterable: Iterable<TSource>;\r\n public constructor(iterable: Iterable<TSource>) {\r\n ArgumentUtility.checkNotOptional({ iterable });\r\n ArgumentUtility.checkIterable({ iterable });\r\n\r\n this.iterable = iterable;\r\n }\r\n\r\n public [Symbol.iterator](): Enumerator<TSource> {\r\n return this.getEnumerator();\r\n }\r\n\r\n public getEnumerator(): Enumerator<TSource> {\r\n return this.iterable[Symbol.iterator]();\r\n }\r\n}\r\n","import { TyneqBaseEnumerator } from \"../enumerators/TyneqBaseEnumerator\";\r\n\r\n/**\r\n * Yields a single value a fixed number of times.\r\n *\r\n * @group Operators\r\n * @category Streaming\r\n * @internal\r\n */\r\nexport class RepeatEnumerator<TSource> extends TyneqBaseEnumerator<TSource> {\r\n private readonly value: TSource;\r\n private readonly count: number;\r\n\r\n private yieldedCount: number = 0;\r\n\r\n public constructor(value: TSource, count: number) {\r\n super();\r\n this.count = count;\r\n this.value = value;\r\n }\r\n\r\n protected override handleNext(): IteratorResult<TSource> {\r\n if (this.yieldedCount >= this.count) {\r\n return this.done();\r\n }\r\n\r\n this.yieldedCount++;\r\n return this.yieldedCount === this.count\r\n ? this.doneWithYield(this.value)\r\n : this.yield(this.value);\r\n }\r\n}\r\n","import { ItemSelector } from \"../../types/utility\";\r\nimport { TyneqBaseEnumerator } from \"../enumerators/TyneqBaseEnumerator\";\r\n\r\n/**\r\n * Yields a sequence produced by repeatedly applying a selector to the previous element.\r\n *\r\n * @group Operators\r\n * @category Streaming\r\n * @internal\r\n */\r\nexport class GenerateEnumerator<TSource, TResult extends TSource> extends TyneqBaseEnumerator<TSource, TResult> {\r\n private readonly nextSelector: ItemSelector<TSource, TResult>;\r\n private readonly count: number;\r\n\r\n private value: TSource;\r\n private yieldedCount: number = 0;\r\n private index: number = 0;\r\n\r\n\r\n public constructor(seed: TSource, next: ItemSelector<TSource, TResult>, count?: number) {\r\n super();\r\n this.value = seed;\r\n this.nextSelector = next;\r\n this.count = count ?? Infinity;\r\n }\r\n\r\n protected override handleNext(): IteratorResult<TResult> {\r\n if (this.yieldedCount >= this.count) {\r\n return this.done();\r\n }\r\n\r\n const result = this.nextSelector(this.value, this.index++);\r\n this.value = result;\r\n this.yieldedCount++;\r\n return this.yield(result);\r\n }\r\n}\r\n","import { Nullable } from \"../../types/utility\";\r\nimport { TyneqBaseEnumerator } from \"../enumerators/TyneqBaseEnumerator\";\r\n\r\n/**\r\n * Yields all elements from each source iterable in order.\r\n *\r\n * @group Operators\r\n * @category Streaming\r\n * @internal\r\n */\r\nexport class SourceConcatEnumerator<TSource> extends TyneqBaseEnumerator<TSource> {\r\n private readonly sources: Iterable<TSource>[];\r\n private currentSourceIndex: number = 0;\r\n private currentIterator: Nullable<Iterator<TSource>> = null;\r\n\r\n public constructor(...sources: Iterable<TSource>[]) {\r\n super();\r\n this.sources = sources;\r\n }\r\n\r\n protected override disposeAdditional(): void {\r\n try {\r\n this.currentIterator?.return?.();\r\n } catch {\r\n // swallow\r\n }\r\n\r\n this.currentIterator = null;\r\n }\r\n\r\n protected override handleNext(): IteratorResult<TSource> {\r\n while (this.currentSourceIndex < this.sources.length) {\r\n if (this.currentIterator === null) {\r\n this.currentIterator = this.sources[this.currentSourceIndex][Symbol.iterator]();\r\n }\r\n\r\n const result = this.currentIterator.next();\r\n if (!result.done) {\r\n return this.yield(result.value);\r\n }\r\n\r\n this.currentIterator = null;\r\n this.currentSourceIndex++;\r\n }\r\n\r\n return this.done();\r\n }\r\n}\r\n","import { RangeEnumerator } from \"./generators/range\";\r\nimport { RandomEnumerator } from \"./generators/random\";\r\nimport { TyneqSequence } from \"../types/core\";\r\nimport { ArgumentUtility } from \"../utility/ArgumentUtility\";\r\nimport { EnumerableAdapter } from \"./EnumerableAdapter\";\r\nimport { TyneqEnumerable } from \"./TyneqEnumerable\";\r\nimport { QueryNode } from \"../queryplan/QueryNode\";\r\nimport type { SourceKind } from \"../types/queryplan\";\r\nimport { source } from \"../plugin/decorators/source\";\r\nimport { ItemSelector, Optional } from \"../types/utility\";\r\nimport { RepeatEnumerator } from \"./generators/repeat\";\r\nimport { GenerateEnumerator } from \"./generators/generate\";\r\nimport { SourceConcatEnumerator } from \"./generators/sourceConcat\";\r\n\r\n/**\r\n * Entry point for creating Tyneq sequences.\r\n *\r\n * @example\r\n * ```ts\r\n * import { Tyneq } from \"tyneq\";\r\n *\r\n * const sum = Tyneq.from([1, 2, 3, 4, 5])\r\n * .where((x) => x % 2 === 0)\r\n * .sum((x) => x); // -> 6\r\n * ```\r\n *\r\n * @group Classes\r\n */\r\nexport class Tyneq {\r\n /**\r\n * Creates a lazy sequence from any `Iterable<T>` (arrays, sets, generators, etc.).\r\n *\r\n * @throws {ArgumentNullError} When `source` is null or undefined.\r\n * @throws {ArgumentTypeError} When `source` is not iterable.\r\n */\r\n @source({ source: \"internal\" })\r\n public static from<TSource>(source: Iterable<TSource>): TyneqSequence<TSource> {\r\n ArgumentUtility.checkNotOptional({ source });\r\n ArgumentUtility.checkIterable({ source });\r\n\r\n const sourceKind = Tyneq.resolveSourceKind(source);\r\n const adapter = new EnumerableAdapter(source);\r\n return new TyneqEnumerable<TSource>(adapter, new QueryNode(\"from\", [source], null, \"source\", sourceKind));\r\n }\r\n\r\n private static resolveSourceKind(source: Iterable<unknown>): SourceKind {\r\n if (Array.isArray(source)) return \"array\";\r\n if (source instanceof Set) return \"set\";\r\n if (source instanceof Map) return \"map\";\r\n if (typeof source === \"string\") return \"string\";\r\n\r\n return \"other\";\r\n }\r\n\r\n /**\r\n * Creates a sequence of `count` elements produced by calling `randomizer` once per element.\r\n *\r\n * @remarks\r\n * Returns an empty sequence when `count === 0`.\r\n *\r\n * @throws {ArgumentOutOfRangeError} When `count` is negative.\r\n * @throws {ArgumentNullError} When `randomizer` is null or undefined.\r\n */\r\n @source({ source: \"internal\" })\r\n public static random<TSource>(count: number, randomizer: () => TSource): TyneqSequence<TSource> {\r\n ArgumentUtility.checkNonNegative({ count });\r\n ArgumentUtility.checkInteger({ count });\r\n ArgumentUtility.checkNotOptional({ randomizer });\r\n\r\n return new TyneqEnumerable<TSource>({\r\n getEnumerator: () => new RandomEnumerator<TSource>(count, randomizer)\r\n }, new QueryNode(\"random\", [count, randomizer], null, \"source\"));\r\n }\r\n\r\n /**\r\n * Returns `true` if `source` is `null`, `undefined`, or an iterable whose first element is `null` or `undefined`.\r\n */\r\n public static isNullOrEmpty<TSource>(source: Optional<Iterable<TSource>>): boolean {\r\n if (source === null || source === undefined) {\r\n return true;\r\n }\r\n\r\n return this.from(source).isNullOrEmpty();\r\n }\r\n\r\n /**\r\n * Creates a sequence of `count` integers starting from `start`.\r\n *\r\n * @remarks\r\n * Returns an empty sequence when `count === 0`.\r\n *\r\n * @example\r\n * ```ts\r\n * Tyneq.range(1, 5).toArray(); // -> [1, 2, 3, 4, 5]\r\n * ```\r\n *\r\n * @throws {ArgumentOutOfRangeError} When `count` is negative.\r\n * @throws {ArgumentError} When `count` is not an integer.\r\n */\r\n @source({ source: \"internal\" })\r\n public static range(start: number, count: number): TyneqSequence<number> {\r\n ArgumentUtility.checkNonNegative({ count });\r\n ArgumentUtility.checkInteger({ count });\r\n\r\n const end = start + count - 1;\r\n return new TyneqEnumerable<number>({\r\n getEnumerator: () => new RangeEnumerator(start, end)\r\n }, new QueryNode(\"range\", [start, count], null, \"source\"));\r\n }\r\n\r\n /** Returns an empty sequence with zero elements. */\r\n @source({ source: \"internal\" })\r\n public static empty<TSource>(): TyneqSequence<TSource> {\r\n return new TyneqEnumerable<TSource>(\r\n new EnumerableAdapter<TSource>([]),\r\n new QueryNode(\"empty\", [], null, \"source\")\r\n );\r\n }\r\n\r\n /**\r\n * Creates a sequence that yields `value` exactly `count` times.\r\n *\r\n * @example\r\n * ```ts\r\n * Tyneq.repeat(\"x\", 3).toArray(); // -> [\"x\", \"x\", \"x\"]\r\n * ```\r\n *\r\n * @throws {ArgumentOutOfRangeError} When `count` is negative.\r\n * @throws {ArgumentError} When `count` is not an integer.\r\n */\r\n @source({ source: \"internal\" })\r\n public static repeat<TSource>(value: TSource, count: number): TyneqSequence<TSource> {\r\n ArgumentUtility.checkNonNegative({ count });\r\n ArgumentUtility.checkInteger({ count });\r\n\r\n return new TyneqEnumerable<TSource>({\r\n getEnumerator: () => new RepeatEnumerator<TSource>(value, count)\r\n }, new QueryNode(\"repeat\", [value, count], null, \"source\"));\r\n }\r\n\r\n /**\r\n * Creates a sequence by repeatedly applying `next` to produce each element from the previous one.\r\n *\r\n * @remarks\r\n * The selector receives `(currentValue, index)`. Each call's return value becomes the input\r\n * for the next call. Omit `count` for an infinite sequence; pair with `take` to bound it.\r\n *\r\n * @example\r\n * ```ts\r\n * Tyneq.generate(1, (x) => x * 2, 4).toArray(); // -> [2, 4, 8, 16]\r\n * ```\r\n *\r\n * @throws {ArgumentNullError} When `next` is null or undefined.\r\n * @throws {ArgumentOutOfRangeError} When `count` is negative.\r\n * @throws {ArgumentError} When `count` is not an integer.\r\n */\r\n @source({ source: \"internal\" })\r\n public static generate<TSource, TResult extends TSource>(seed: TSource, next: ItemSelector<TSource, TResult>, count?: number): TyneqSequence<TResult> {\r\n ArgumentUtility.checkNotOptional({ next });\r\n if (count !== undefined) {\r\n ArgumentUtility.checkNonNegative({ count });\r\n ArgumentUtility.checkInteger({ count });\r\n }\r\n\r\n return new TyneqEnumerable<TResult>({\r\n getEnumerator: () => new GenerateEnumerator<TSource, TResult>(seed, next, count)\r\n }, new QueryNode(\"generate\", [seed, next, count], null, \"source\"));\r\n }\r\n\r\n /**\r\n * Creates a sequence that yields all elements from each source in order.\r\n *\r\n * @remarks\r\n * Returns an empty sequence when called with no arguments.\r\n *\r\n * @example\r\n * ```ts\r\n * Tyneq.concat([1, 2], [3, 4], [5]).toArray(); // -> [1, 2, 3, 4, 5]\r\n * ```\r\n * \r\n * @throws {ArgumentNullError} When any `source` is null or undefined.\r\n * @throws {ArgumentTypeError} When any `source` is not iterable.\r\n */\r\n @source({ source: \"internal\" })\r\n public static concat<TSource>(...sources: Iterable<TSource>[]): TyneqSequence<TSource> {\r\n for (const source of sources) {\r\n ArgumentUtility.checkNotOptional({ source });\r\n ArgumentUtility.checkIterable({ source });\r\n }\r\n\r\n return new TyneqEnumerable<TSource>({\r\n getEnumerator: () => new SourceConcatEnumerator<TSource>(...sources)\r\n }, new QueryNode(\"concat\", sources, null, \"source\"));\r\n }\r\n\r\n /**\r\n * Pairs each element with its zero-based index.\r\n *\r\n * @remarks\r\n * Each iteration produces independent index counters - safe to re-enumerate.\r\n *\r\n * @example\r\n * ```ts\r\n * Tyneq.enumerate([\"a\", \"b\", \"c\"]).toArray();\r\n * // -> [[0, \"a\"], [1, \"b\"], [2, \"c\"]]\r\n * ```\r\n *\r\n * @throws {ArgumentNullError} When `source` is null or undefined.\r\n * @throws {ArgumentTypeError} When `source` is not iterable.\r\n */\r\n public static enumerate<TSource>(source: Iterable<TSource>): TyneqSequence<[number, TSource]> {\r\n ArgumentUtility.checkNotOptional({ source });\r\n ArgumentUtility.checkIterable({ source });\r\n // A fresh `index` counter is created per enumeration via [Symbol.iterator],\r\n // preventing the shared-counter bug that occurs when the result is re-enumerated.\r\n return this.from({\r\n *[Symbol.iterator]() {\r\n let index = 0;\r\n for (const item of source) yield [index++, item] as [number, TSource];\r\n }\r\n });\r\n }\r\n}\r\n","import { TyneqError } from \"./TyneqError\";\r\n\r\n/**\r\n * Thrown when a lookup is performed with a key that does not exist in the collection.\r\n *\r\n * @example\r\n * ```ts\r\n * try { seq.toMap((x) => x.id).get(999); }\r\n * catch (e) { if (e instanceof KeyNotFoundError) { ... } }\r\n * ```\r\n *\r\n * @see {@link TyneqError}\r\n * @group Errors\r\n */\r\nexport class KeyNotFoundError extends TyneqError {\r\n public constructor(message = \"The given key was not present in the dictionary.\", inner?: Error) {\r\n super(message, { inner });\r\n }\r\n}\r\n","import { TyneqError } from \"./TyneqError\";\r\n\r\n/**\r\n * Thrown when a requested operation is not supported.\r\n *\r\n * @example\r\n * ```ts\r\n * try { iterator.throw?.(new Error()); }\r\n * catch (e) { if (e instanceof NotSupportedError) { ... } }\r\n * ```\r\n *\r\n * @see {@link TyneqError}\r\n * @group Errors\r\n */\r\nexport class NotSupportedError extends TyneqError {\r\n public constructor(message = \"The requested operation is not supported.\", inner?: Error) {\r\n super(message, { inner });\r\n }\r\n}\r\n","import { Maybe } from \"../../types/utility\";\r\nimport { TyneqError } from \"./TyneqError\";\r\n\r\n/**\r\n * Thrown when the query plan compiler encounters a structural or semantic error\r\n * while compiling a query plan into an executable sequence.\r\n *\r\n * @example\r\n * ```ts\r\n * try { compiler.compile(plan); }\r\n * catch (e) {\r\n * if (e instanceof CompilerError) {\r\n * console.log(e.operatorName, e.phase, e.message);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link TyneqError}\r\n * @group Errors\r\n */\r\nexport class CompilerError extends TyneqError {\r\n /** The name of the operator being compiled when the error occurred, if known. */\r\n public readonly operatorName: Maybe<string>;\r\n\r\n /**\r\n * The compilation phase in which the error occurred.\r\n * - `\"transform\"` - during query plan transformation (pre-compile)\r\n * - `\"source\"` - while compiling a source node\r\n * - `\"operator\"` - while applying an operator node\r\n */\r\n public readonly phase: \"transform\" | \"source\" | \"operator\";\r\n\r\n public constructor(\r\n message: string,\r\n phase: \"transform\" | \"source\" | \"operator\",\r\n operatorName?: string,\r\n inner?: Error\r\n ) {\r\n super(message, { inner });\r\n this.phase = phase;\r\n this.operatorName = operatorName;\r\n }\r\n}\r\n","import type { QueryPlanNode, QueryPlanVisitor, QueryPlanPrinterOptions } from \"../types/queryplan\";\r\nimport type { Nullable } from \"../types/utility\";\r\n\r\n/**\r\n * Converts a query plan tree into a human-readable multi-line string.\r\n *\r\n * Implements `QueryPlanVisitor<string>`. The output lists operators from source to\r\n * terminal, one per line, with indentation showing the pipeline depth.\r\n *\r\n * @example\r\n * ```ts\r\n * import { QueryPlanPrinter } from \"tyneq/queryplan\";\r\n *\r\n * const seq = Tyneq.range(1, 10).where(x => x % 2 === 0).select(x => x * x);\r\n * console.log(QueryPlanPrinter.print(seq[tyneqQueryNode]!));\r\n * // range(1, 10)\r\n * // -> where(<fn>)\r\n * // -> select(<fn>)\r\n * ```\r\n *\r\n * @group QueryPlan\r\n */\r\nexport class QueryPlanPrinter implements QueryPlanVisitor<string> {\r\n protected readonly indent: string;\r\n protected readonly arrow: string;\r\n protected readonly maxInlineArrayItems: number;\r\n\r\n public constructor(options: QueryPlanPrinterOptions = {}) {\r\n this.indent = options.indent ?? \" \";\r\n this.arrow = options.arrow ?? \"->\";\r\n this.maxInlineArrayItems = options.maxInlineArrayItems ?? 3;\r\n }\r\n\r\n /** Renders the full query plan rooted at `node` as a multi-line string. */\r\n public visit(node: QueryPlanNode): string {\r\n const result = this.buildPlan(node);\r\n return result;\r\n }\r\n\r\n /** Convenience static: creates a printer with `options` and calls `visit(node)`. */\r\n public static print(node: QueryPlanNode, options?: QueryPlanPrinterOptions): string {\r\n return new QueryPlanPrinter(options).visit(node);\r\n }\r\n\r\n /**\r\n * Formats a single operator argument for display.\r\n * Override to customise how arguments appear in printed plans.\r\n */\r\n protected formatArg(arg: unknown): string {\r\n if (typeof arg === \"function\") return \"<fn>\";\r\n if (arg === null) return \"null\";\r\n if (arg === undefined) return \"undefined\";\r\n if (typeof arg === \"string\") return `\"${arg}\"`;\r\n if (Array.isArray(arg)) {\r\n if (arg.length === 0) return \"[]\";\r\n if (arg.length <= this.maxInlineArrayItems) {\r\n return `[${arg.map((a) => this.formatArg(a)).join(\", \")}]`;\r\n }\r\n\r\n return `[...${arg.length} items]`;\r\n }\r\n if (typeof arg === \"object\") return \"{...}\";\r\n\r\n return String(arg);\r\n }\r\n\r\n /**\r\n * Formats one line of the plan output.\r\n * Override to customise indentation or arrow style beyond what `QueryPlanPrinterOptions` allows.\r\n */\r\n protected formatLine(name: string, argStr: string, isRoot: boolean): string {\r\n const prefix = isRoot ? \"\" : `${this.indent}${this.arrow} `;\r\n return `${prefix}${name}(${argStr})`;\r\n }\r\n\r\n private buildPlan(node: QueryPlanNode): string {\r\n const nodes = this.collectNodes(node);\r\n const lines = nodes.map((n, index) => {\r\n const argStr = n.args.map((a) => this.formatArg(a)).join(\", \");\r\n return this.formatLine(n.operatorName, argStr, index === 0);\r\n });\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n \r\n private collectNodes(node: QueryPlanNode): QueryPlanNode[] {\r\n const nodes: QueryPlanNode[] = [];\r\n let current: Nullable<QueryPlanNode> = node;\r\n while (current !== null) {\r\n nodes.push(current);\r\n current = current.source;\r\n }\r\n\r\n nodes.reverse();\r\n\r\n return nodes;\r\n }\r\n}\r\n","import type { QueryPlanNode, QueryPlanTraversalDirection, QueryPlanVisitor, QueryPlanWalkerOptions } from \"../types/queryplan\";\r\nimport { Maybe } from \"../types/utility\";\r\n\r\n/**\r\n * Concrete base class for side-effect query plan visitors.\r\n *\r\n * @remarks\r\n * Traverses the node chain calling {@link QueryPlanWalker.visitNode} once per node.\r\n * The traversal direction defaults to `\"source-to-terminal\"` (bottom-up: `from` before\r\n * `where` before `select`) and can be changed to `\"terminal-to-source\"` (top-down) via\r\n * the options object.\r\n *\r\n * ### Usage patterns\r\n *\r\n * **Direct instantiation with a callback** - no subclass needed for simple traversals:\r\n * ```ts\r\n * const names: string[] = [];\r\n * new QueryPlanWalker({ callback: node => names.push(node.operatorName) }).visit(plan);\r\n * ```\r\n *\r\n * **Subclass** - for stateful walkers that accumulate results across nodes:\r\n * ```ts\r\n * class NodeCounter extends QueryPlanWalker {\r\n * public count = 0;\r\n * protected override visitNode(_node: QueryPlanNode): void { this.count++; }\r\n * }\r\n *\r\n * const counter = new NodeCounter();\r\n * counter.visit(seq[tyneqQueryNode]!);\r\n * console.log(counter.count); // number of operators in the pipeline\r\n * ```\r\n *\r\n * **Top-down traversal:**\r\n * ```ts\r\n * new QueryPlanWalker({\r\n * callback: node => console.log(node.operatorName),\r\n * direction: \"terminal-to-source\",\r\n * }).visit(plan);\r\n * ```\r\n *\r\n * **Subclass with direction override** - pass options to `super`:\r\n * ```ts\r\n * class ReverseCollector extends QueryPlanWalker {\r\n * public readonly names: string[] = [];\r\n * public constructor() { super({ direction: \"terminal-to-source\" }); }\r\n * protected override visitNode(node: QueryPlanNode): void {\r\n * this.names.push(node.operatorName);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @group QueryPlan\r\n */\r\nexport class QueryPlanWalker implements QueryPlanVisitor<void> {\r\n\r\n private readonly callback: Maybe<(node: QueryPlanNode) => void>;\r\n private readonly direction: QueryPlanTraversalDirection;\r\n\r\n /**\r\n * @param options - Optional configuration for the walker.\r\n */\r\n public constructor(options?: QueryPlanWalkerOptions) {\r\n this.callback = options?.callback;\r\n this.direction = options?.direction ?? \"source-to-terminal\";\r\n }\r\n\r\n /**\r\n * Walks the full chain rooted at `node`, calling {@link visitNode} for each node\r\n * in the configured direction.\r\n */\r\n public visit(node: QueryPlanNode): void {\r\n if (this.direction === \"source-to-terminal\") {\r\n if (node.source !== null) {\r\n this.visit(node.source);\r\n }\r\n\r\n this.visitNode(node);\r\n } else {\r\n this.visitNode(node);\r\n\r\n if (node.source !== null) {\r\n this.visit(node.source);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Called once per node during traversal.\r\n *\r\n * @remarks\r\n * The default implementation fires the callback passed via options (if any).\r\n * Override this method in a subclass to provide custom behaviour. Subclasses that\r\n * override this method decide whether to call `super.visitNode(node)` to also fire\r\n * the options callback.\r\n *\r\n * @param node - The current node being visited.\r\n */\r\n protected visitNode(node: QueryPlanNode): void {\r\n this.callback?.(node);\r\n }\r\n}\r\n","import type { QueryPlanNode, QueryPlanVisitor } from \"../types/queryplan\";\r\nimport { QueryNode } from \"./QueryNode\";\r\nimport type { Nullable } from \"../types/utility\";\r\n\r\n/**\r\n * Base class for immutable query plan rewriting.\r\n *\r\n * @remarks\r\n * Recursively rebuilds the node chain, calling {@link QueryPlanTransformer.transformNode}\r\n * once per node. The default implementation is an **identity transform** - every node is\r\n * reconstructed with the same data, producing a structurally equivalent copy.\r\n *\r\n * Subclasses override `transformNode` to intercept specific operators. Three rewrite\r\n * patterns are possible:\r\n *\r\n * - **Rewrite a node** - return a new `QueryNode` with different `operatorName` or `args`\r\n * - **Remove a node** - return `source` directly, skipping this node\r\n * - **Collapse two nodes into one** - use `source` as the new node's `source` (fusing\r\n * the current node with its already-transformed predecessor)\r\n *\r\n * @example\r\n * ```ts\r\n * // Rename all 'where' nodes to 'filter' in the plan view\r\n * class RenameWhere extends QueryPlanTransformer {\r\n * protected override transformNode(node: QueryPlanNode, source: QueryPlanNode | null): QueryPlanNode {\r\n * if (node.operatorName === \"where\") {\r\n * return new QueryNode(\"filter\", node.args, source, node.category);\r\n * }\r\n * return super.transformNode(node, source);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @group QueryPlan\r\n */\r\nexport class QueryPlanTransformer implements QueryPlanVisitor<QueryPlanNode> {\r\n\r\n /**\r\n * Transforms the full chain rooted at `node` and returns the new root node.\r\n *\r\n * @remarks\r\n * Processes source-first (bottom-up): the source chain is fully transformed before\r\n * `transformNode` is called for the current node. This means `source` passed to\r\n * `transformNode` is always already the transformed predecessor.\r\n */\r\n public visit(node: QueryPlanNode): QueryPlanNode {\r\n const transformedSource = node.source !== null ? this.visit(node.source) : null;\r\n return this.transformNode(node, transformedSource);\r\n }\r\n\r\n /**\r\n * Transforms a single node. Override to intercept specific operators.\r\n *\r\n * @remarks\r\n * The default implementation reconstructs the node with identical data (identity transform).\r\n * `source` is the already-transformed predecessor - use it as the `source` of any returned\r\n * node to preserve chain continuity.\r\n *\r\n * @param node - The original node (unmodified).\r\n * @param source - The transformed predecessor, or `null` for source nodes.\r\n */\r\n protected transformNode(node: QueryPlanNode, source: Nullable<QueryPlanNode>): QueryPlanNode {\r\n return new QueryNode(node.operatorName, node.args, source, node.category, node.sourceKind);\r\n }\r\n}\r\n","import type { QueryPlanNode } from \"../types/queryplan\";\r\nimport type { Nullable } from \"../types/utility\";\r\nimport { QueryNode } from \"./QueryNode\";\r\nimport { QueryPlanTransformer } from \"./QueryPlanTransformer\";\r\n\r\n/**\r\n * A built-in {@link QueryPlanTransformer} that fuses redundant consecutive operators.\r\n *\r\n * @remarks\r\n * **This optimizer rewrites the query plan tree only - it does not affect execution of the\r\n * original sequence.** The returned `QueryPlanNode` reflects what an optimized pipeline would\r\n * look like; the live sequence that produced the original plan is unchanged.\r\n *\r\n * **Fusion is only semantics-preserving for pure, side-effect-free functions.**\r\n * If a predicate or projection has side effects (e.g. logging, mutation), fusing two nodes into\r\n * one changes when and how many times those effects fire. For example, in a fused `where`, the\r\n * second predicate is never called for items that fail the first - any mutation inside the second\r\n * predicate is skipped for those items. Do not use this optimizer on pipelines with impure\r\n * predicates or projections.\r\n *\r\n * ### Fusions applied\r\n *\r\n * | Pattern | Result |\r\n * |---------|--------|\r\n * | `where(a) -> where(b)` | `where(x => a(x) && b(x))` |\r\n * | `select(a) -> select(b)` | `select(x => b(a(x)))` |\r\n *\r\n * Additional fusions can be added by subclassing and overriding\r\n * {@link QueryPlanTransformer.transformNode}.\r\n *\r\n * @example\r\n * ```ts\r\n * import { Tyneq, tyneqQueryNode, QueryPlanOptimizer, QueryPlanPrinter } from \"tyneq\";\r\n *\r\n * const seq = Tyneq.from([1, 2, 3])\r\n * .where(x => x > 1)\r\n * .where(x => x < 3)\r\n * .select(x => x * 2)\r\n * .select(x => x + 1);\r\n *\r\n * const original = seq[tyneqQueryNode]!;\r\n * const optimized = new QueryPlanOptimizer().visit(original);\r\n *\r\n * console.log(QueryPlanPrinter.print(original));\r\n * // from([...])\r\n * // -> where(<fn>)\r\n * // -> where(<fn>)\r\n * // -> select(<fn>)\r\n * // -> select(<fn>)\r\n *\r\n * console.log(QueryPlanPrinter.print(optimized));\r\n * // from([...])\r\n * // -> where(<fn>)\r\n * // -> select(<fn>)\r\n * ```\r\n *\r\n * @group QueryPlan\r\n */\r\nexport class QueryPlanOptimizer extends QueryPlanTransformer {\r\n\r\n protected override transformNode(node: QueryPlanNode, source: Nullable<QueryPlanNode>): QueryPlanNode {\r\n if (node.operatorName === \"where\" && source?.operatorName === \"where\") {\r\n return this.fuseWhere(node, source);\r\n }\r\n\r\n if (node.operatorName === \"select\" && source?.operatorName === \"select\") {\r\n return this.fuseSelect(node, source);\r\n }\r\n\r\n return super.transformNode(node, source);\r\n }\r\n\r\n /**\r\n * @remarks Fusion is only semantics-preserving for pure, side-effect-free predicates.\r\n */\r\n private fuseWhere(node: QueryPlanNode, source: QueryPlanNode): QueryPlanNode {\r\n const predA = source.args[0] as (x: unknown) => boolean;\r\n const predB = node.args[0] as (x: unknown) => boolean;\r\n const fused = (x: unknown): boolean => predA(x) && predB(x);\r\n return new QueryNode(\"where\", [fused], source.source, \"streaming\");\r\n }\r\n\r\n /**\r\n * @remarks Fusion is only semantics-preserving for pure, side-effect-free projections.\r\n */\r\n private fuseSelect(node: QueryPlanNode, source: QueryPlanNode): QueryPlanNode {\r\n const projA = source.args[0] as (x: unknown) => unknown;\r\n const projB = node.args[0] as (x: unknown) => unknown;\r\n const fused = (x: unknown): unknown => projB(projA(x));\r\n return new QueryNode(\"select\", [fused], source.source, \"streaming\");\r\n }\r\n}\r\n","import { TyneqSequence, SequenceConstructor } from \"../../types/core\";\r\nimport { QueryPlanNode } from \"../../types/queryplan\";\r\nimport { QueryPlanTransformer } from \"../QueryPlanTransformer\";\r\nimport { OperatorRegistry } from \"../../core/registry/TyneqOperatorRegistry\";\r\nimport { CompilerError } from \"../../core/errors/CompilerError\";\r\n\r\n/**\r\n * Options for {@link QueryPlanCompiler.compile} and {@link QueryPlanCompiler.compileRaw}.\r\n *\r\n * @group QueryPlan\r\n */\r\nexport interface CompileOptions {\r\n /**\r\n * Replaces the source data when compiling.\r\n *\r\n * When provided, the compiler passes this value as the first argument to the source\r\n * operator instead of the value stored in the plan node's `args`. This lets you reuse\r\n * the same pipeline structure (operators, predicates, projections) against a different\r\n * data set without rebuilding the sequence.\r\n *\r\n * @example\r\n * ```ts\r\n * const plan = Tyneq.from([1, 2, 3]).where(x => x > 1).select(x => x * 2)[tyneqQueryNode]!;\r\n * const compiler = new QueryPlanCompiler();\r\n *\r\n * compiler.compile(plan).toArray(); // -> [4, 6]\r\n * compiler.compile(plan, { source: [10, 20, 30] }).toArray(); // -> [40, 60]\r\n * ```\r\n *\r\n * @remarks\r\n * Only affects source nodes (the root of the plan). All operator nodes are replayed\r\n * exactly as recorded. If the plan has no source node (e.g. it starts from an operator\r\n * node with a missing parent), this option has no effect.\r\n */\r\n readonly source?: Iterable<unknown>;\r\n}\r\n\r\n/**\r\n * Compiles a query plan tree into an executable `TyneqSequence`.\r\n *\r\n * @remarks\r\n * Walks the `QueryPlanNode` chain from source to terminal, reconstructing each operator by\r\n * looking it up in the `OperatorRegistry` and applying it to the compiled source.\r\n * An optional list of `QueryPlanTransformer` instances runs before compilation, allowing\r\n * optimization or rewriting of the plan.\r\n *\r\n * @example\r\n * ```ts\r\n * import { Tyneq, tyneqQueryNode, QueryPlanCompiler, QueryPlanOptimizer } from \"tyneq\";\r\n *\r\n * const seq = Tyneq.from([1, 2, 3]).where(x => x > 1).select(x => x * 2);\r\n * const compiler = new QueryPlanCompiler([new QueryPlanOptimizer()]);\r\n * const result = compiler.compile(seq[tyneqQueryNode]!);\r\n * result.toArray(); // -> [4, 6]\r\n * ```\r\n *\r\n * @group QueryPlan\r\n */\r\nexport class QueryPlanCompiler {\r\n private readonly transformers: QueryPlanTransformer[];\r\n\r\n public constructor(transformers: Iterable<QueryPlanTransformer> = []) {\r\n this.transformers = [...transformers];\r\n }\r\n\r\n /**\r\n * Compile a query plan into an executable sequence.\r\n *\r\n * Runs all registered transformers before compiling. Use {@link compileRaw} to skip\r\n * the transform phase when the plan is already optimised.\r\n *\r\n * @param node - The root node of the query plan to compile.\r\n * @param options - Optional compile-time overrides. Use `options.source` to supply a\r\n * different data source than the one stored in the plan.\r\n * @returns The compiled sequence typed as `TyneqSequence<T>` by default.\r\n * If you know the plan ends in an operator that returns a subtype (e.g. `orderBy` ->\r\n * `TyneqOrderedSequence`, `memoize` -> `TyneqCachedSequence`), supply `TResult` explicitly:\r\n * `compiler.compile<number, TyneqOrderedSequence<number>>(node)`.\r\n */\r\n public compile<T = unknown, TResult extends TyneqSequence<T> = TyneqSequence<T>>(node: QueryPlanNode, options?: CompileOptions): TResult {\r\n if (node === null || node === undefined) {\r\n throw new CompilerError(\r\n \"compile() received a null or undefined query plan node. Ensure the sequence was created via Tyneq.from(), Tyneq.range(), or another source operator before compiling.\",\r\n \"source\"\r\n );\r\n }\r\n\r\n const transformedNode = this.transform(node);\r\n return this.compileNode(transformedNode, options) as TResult;\r\n }\r\n\r\n /**\r\n * Compile a pre-optimised query plan into an executable sequence, skipping the\r\n * transform phase.\r\n *\r\n * @remarks\r\n * Use this overload when you have already run transformers externally (or deliberately\r\n * want to bypass them) and want to compile the node as-is. Equivalent to constructing\r\n * a `QueryPlanCompiler` with no transformers and calling `compile()`.\r\n *\r\n * @param node - The root node of the already-transformed query plan to compile.\r\n * @param options - Optional compile-time overrides. Use `options.source` to supply a\r\n * different data source than the one stored in the plan.\r\n */\r\n public compileRaw<T = unknown, TResult extends TyneqSequence<T> = TyneqSequence<T>>(node: QueryPlanNode, options?: CompileOptions): TResult {\r\n if (node === null || node === undefined) {\r\n throw new CompilerError(\r\n \"compileRaw() received a null or undefined query plan node. Ensure the sequence was created via Tyneq.from(), Tyneq.range(), or another source operator before compiling.\",\r\n \"source\"\r\n );\r\n }\r\n\r\n return this.compileNode(node, options) as TResult;\r\n }\r\n\r\n private transform(node: QueryPlanNode): QueryPlanNode {\r\n let transformedNode = node;\r\n for (const transformer of this.transformers) {\r\n try {\r\n transformedNode = transformer.visit(transformedNode);\r\n } catch (e) {\r\n throw new CompilerError(\r\n `Transformer \"${(transformer as { constructor: { name: string } }).constructor.name}\" threw during transformation.`,\r\n \"transform\",\r\n undefined,\r\n e instanceof Error ? e : undefined\r\n );\r\n }\r\n }\r\n\r\n return transformedNode;\r\n }\r\n\r\n private compileNode(node: QueryPlanNode, options?: CompileOptions): unknown {\r\n if (node.category === \"source\") {\r\n return this.compileSource(node, options);\r\n }\r\n\r\n if (node.source === null) {\r\n throw new CompilerError(\r\n \"Operator node is missing a source node. Every operator node must have a source.\",\r\n \"operator\",\r\n node.operatorName\r\n );\r\n }\r\n\r\n return this.applyOperator(this.compileNode(node.source, options), node);\r\n }\r\n\r\n private compileSource(node: QueryPlanNode, options?: CompileOptions): unknown {\r\n const entry = OperatorRegistry.getSource(node.operatorName);\r\n if (!entry) {\r\n throw new CompilerError(\r\n `Unknown source operator \"${node.operatorName}\". ` +\r\n \"Register it via OperatorRegistry.registerSource() before compiling.\",\r\n \"source\",\r\n node.operatorName\r\n );\r\n }\r\n\r\n const args = options?.source !== undefined\r\n ? [options.source, ...node.args.slice(1)]\r\n : [...node.args];\r\n\r\n return entry.impl.apply(null as never, args);\r\n }\r\n\r\n private applyOperator(source: unknown, node: QueryPlanNode): unknown {\r\n const entry = this.findOperatorEntry(node.operatorName, source);\r\n\r\n if (!entry) {\r\n const sourceType = source !== null && source !== undefined\r\n ? Object.getPrototypeOf(source)?.constructor?.name ?? typeof source\r\n : \"null\";\r\n const knownForAnyTarget = OperatorRegistry.hasOperator(node.operatorName);\r\n const message = knownForAnyTarget\r\n ? `Operator \"${node.operatorName}\" is not registered for sequence type ${sourceType}. ` +\r\n \"Ensure the source sequence is of the correct type for this operator.\"\r\n : `Operator \"${node.operatorName}\" is not registered. ` +\r\n \"Register it via @operator, createOperator, or createGeneratorOperator before compiling.\";\r\n throw new CompilerError(message, \"operator\", node.operatorName);\r\n }\r\n\r\n return entry.impl.apply(source as never, [...node.args]);\r\n }\r\n\r\n // Walk the prototype chain of source to find the most-specific registered entry.\r\n private findOperatorEntry(operatorName: string, source: unknown): ReturnType<typeof OperatorRegistry.getOperator> {\r\n if (source === null || source === undefined) {\r\n return undefined;\r\n }\r\n\r\n let proto = Object.getPrototypeOf(source) as object | null;\r\n while (proto !== null) {\r\n const ctor = (proto as { constructor?: SequenceConstructor }).constructor;\r\n if (ctor !== undefined) {\r\n const entry = OperatorRegistry.getOperator(operatorName, ctor);\r\n if (entry !== undefined) {\r\n return entry;\r\n }\r\n }\r\n\r\n proto = Object.getPrototypeOf(proto) as object | null;\r\n }\r\n\r\n return undefined;\r\n }\r\n}"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_TyneqCachedTerminalOperator = require("../TyneqCachedTerminalOperator.cjs");
|
|
3
|
+
exports.EnumeratorUtility = require_TyneqCachedTerminalOperator.EnumeratorUtility;
|
|
4
|
+
exports.TyneqBaseEnumerator = require_TyneqCachedTerminalOperator.TyneqBaseEnumerator;
|
|
5
|
+
exports.TyneqCachedEnumerator = require_TyneqCachedTerminalOperator.TyneqCachedEnumerator;
|
|
6
|
+
exports.TyneqCachedTerminalOperator = require_TyneqCachedTerminalOperator.TyneqCachedTerminalOperator;
|
|
7
|
+
exports.TyneqEnumerator = require_TyneqCachedTerminalOperator.TyneqEnumerator;
|
|
8
|
+
exports.TyneqOrderedEnumerator = require_TyneqCachedTerminalOperator.TyneqOrderedEnumerator;
|
|
9
|
+
exports.TyneqOrderedTerminalOperator = require_TyneqCachedTerminalOperator.TyneqOrderedTerminalOperator;
|
|
10
|
+
exports.TyneqTerminalOperator = require_TyneqCachedTerminalOperator.TyneqTerminalOperator;
|
|
11
|
+
exports.cachedOperator = require_TyneqCachedTerminalOperator.cachedOperator;
|
|
12
|
+
exports.cachedTerminal = require_TyneqCachedTerminalOperator.cachedTerminal;
|
|
13
|
+
exports.createCachedOperator = require_TyneqCachedTerminalOperator.createCachedOperator;
|
|
14
|
+
exports.createCachedTerminalOperator = require_TyneqCachedTerminalOperator.createCachedTerminalOperator;
|
|
15
|
+
exports.createGeneratorOperator = require_TyneqCachedTerminalOperator.createGeneratorOperator;
|
|
16
|
+
exports.createOperator = require_TyneqCachedTerminalOperator.createOperator;
|
|
17
|
+
exports.createOrderedOperator = require_TyneqCachedTerminalOperator.createOrderedOperator;
|
|
18
|
+
exports.createOrderedTerminalOperator = require_TyneqCachedTerminalOperator.createOrderedTerminalOperator;
|
|
19
|
+
exports.createTerminalOperator = require_TyneqCachedTerminalOperator.createTerminalOperator;
|
|
20
|
+
exports.operator = require_TyneqCachedTerminalOperator.operator;
|
|
21
|
+
exports.orderedOperator = require_TyneqCachedTerminalOperator.orderedOperator;
|
|
22
|
+
exports.orderedTerminal = require_TyneqCachedTerminalOperator.orderedTerminal;
|
|
23
|
+
exports.source = require_TyneqCachedTerminalOperator.source;
|
|
24
|
+
exports.terminal = require_TyneqCachedTerminalOperator.terminal;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Q as Optional, a as Enumerator, p as OperatorSource } from "../core.cjs";
|
|
2
|
+
import { S as operator, _ as cachedTerminal, a as TyneqOrderedEnumerator, b as cachedOperator, c as createCachedTerminalOperator, d as createCachedOperator, g as createOperator, h as createGeneratorOperator, i as TyneqCachedEnumerator, l as createOrderedTerminalOperator, n as TyneqOrderedTerminalOperator, o as TyneqEnumerator, p as createOrderedOperator, r as TyneqTerminalOperator, s as TyneqBaseEnumerator, t as TyneqCachedTerminalOperator, u as createTerminalOperator, v as orderedTerminal, x as orderedOperator, y as terminal } from "../TyneqCachedTerminalOperator.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/plugin/decorators/source.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Options for the {@link source} decorator.
|
|
7
|
+
*/
|
|
8
|
+
interface SourceDecoratorOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The operator name used to look up this source in the registry.
|
|
11
|
+
* Must match the `operatorName` on the `QueryPlanNode`.
|
|
12
|
+
* Defaults to the decorated method's name when omitted.
|
|
13
|
+
*/
|
|
14
|
+
readonly name?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether this is a built-in (`"internal"`) or third-party (`"external"`) source.
|
|
17
|
+
* Defaults to `"external"`.
|
|
18
|
+
*/
|
|
19
|
+
readonly source?: OperatorSource;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Static method decorator that registers the decorated method as a source operator.
|
|
23
|
+
*
|
|
24
|
+
* The method itself becomes the factory: when the compiler resolves a source node
|
|
25
|
+
* whose `operatorName` matches the registered name, it calls the method with the
|
|
26
|
+
* node's `args`. No duplication of implementation - the registration points directly
|
|
27
|
+
* at the method.
|
|
28
|
+
*
|
|
29
|
+
* The operator name defaults to the method name, so `@source()` is sufficient when
|
|
30
|
+
* they match.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Optional config. Omit entirely to use all defaults.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { source } from "tyneq/plugin";
|
|
37
|
+
* import { Tyneq } from "tyneq";
|
|
38
|
+
*
|
|
39
|
+
* class MySources {
|
|
40
|
+
* @source()
|
|
41
|
+
* public static fibonacci(count: number): ReturnType<typeof Tyneq.range> {
|
|
42
|
+
* // registered as "fibonacci"
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* @source({ name: "fib2", source: "external" })
|
|
46
|
+
* public static fibonacci2(count: number): ReturnType<typeof Tyneq.range> {
|
|
47
|
+
* // registered as "fib2"
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @group Decorators
|
|
53
|
+
*/
|
|
54
|
+
declare function source(options?: SourceDecoratorOptions): <TMethod extends (...args: any[]) => any>(method: TMethod, context: ClassMethodDecoratorContext & {
|
|
55
|
+
static: true;
|
|
56
|
+
}) => void;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/utility/EnumeratorUtility.d.ts
|
|
59
|
+
/**
|
|
60
|
+
* Low-level helpers for working with `Enumerator<T>` objects inside custom operator enumerators.
|
|
61
|
+
*
|
|
62
|
+
* Import from `"tyneq/plugin"` when writing class-based operators that need to convert
|
|
63
|
+
* between `Iterable<T>` and `Enumerator<T>`, or that need safe cleanup via `tryDispose`.
|
|
64
|
+
*
|
|
65
|
+
* @group Plugin Utilities
|
|
66
|
+
*/
|
|
67
|
+
declare class EnumeratorUtility {
|
|
68
|
+
private constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Calls `enumerator.return()` if it exists, swallowing any error.
|
|
71
|
+
* Safe to call on `null` or `undefined`.
|
|
72
|
+
*/
|
|
73
|
+
static tryDispose<TSource>(enumerator: Optional<Enumerator<TSource>>): void;
|
|
74
|
+
/** Wraps an `Enumerator<T>` in a minimal `Iterable<T>` adapter (no buffering). */
|
|
75
|
+
static toIterable<TSource>(enumerator: Enumerator<TSource>): Iterable<TSource>;
|
|
76
|
+
/** Gets an `Enumerator<T>` from any `Iterable<T>`. */
|
|
77
|
+
static fromIterable<TSource>(iterable: Iterable<TSource>): Enumerator<TSource>;
|
|
78
|
+
/**
|
|
79
|
+
* Advances the enumerator by one position and returns `true` if that position was done.
|
|
80
|
+
*
|
|
81
|
+
* **Warning:** this calls `next()` and irrevocably consumes one element.
|
|
82
|
+
* If the enumerator is not exhausted, the yielded element is discarded.
|
|
83
|
+
* Only call this when advancing past the current position is intentional.
|
|
84
|
+
*/
|
|
85
|
+
static checkAndConsume<TSource>(enumerator: Enumerator<TSource>): boolean;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { EnumeratorUtility, TyneqBaseEnumerator, TyneqCachedEnumerator, TyneqCachedTerminalOperator, TyneqEnumerator, TyneqOrderedEnumerator, TyneqOrderedTerminalOperator, TyneqTerminalOperator, cachedOperator, cachedTerminal, createCachedOperator, createCachedTerminalOperator, createGeneratorOperator, createOperator, createOrderedOperator, createOrderedTerminalOperator, createTerminalOperator, operator, orderedOperator, orderedTerminal, source, terminal };
|
|
89
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/plugin/decorators/source.ts","../../src/utility/EnumeratorUtility.ts"],"mappings":";;;;;;;UAMiB,sBAAA;EAAsB;;;;;EAAA,SAM1B,IAAA;EAKuB;;AAoCpC;;EApCoC,SAAvB,MAAA,GAAS,cAAA;AAAA;;;;;;;;;;;;;;;;;;;ACNtB;;;;;;;;;;;;;;;iBD0CgB,MAAA,CAAO,OAAA,GAAS,sBAAA,wBACS,IAAA,iBACjC,MAAA,EAAQ,OAAA,EACR,OAAA,EAAS,2BAAA;EAAgC,MAAA;AAAA;;;;;AAlDjD;;;;;;cCKa,iBAAA;EAAA,QACF,WAAA,CAAA;EDKyB;AAoCpC;;;EApCoC,OCClB,UAAA,SAAA,CAAoB,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,OAAA;EDqCtD;EAAA,OC5BE,UAAA,SAAA,CAAoB,UAAA,EAAY,UAAA,CAAW,OAAA,IAAW,QAAA,CAAS,OAAA;ED6BrC;EAAA,OCtB1B,YAAA,SAAA,CAAsB,QAAA,EAAU,QAAA,CAAS,OAAA,IAAW,UAAA,CAAW,OAAA;EDmBjD;;;;;;;EAAA,OCRd,eAAA,SAAA,CAAyB,UAAA,EAAY,UAAA,CAAW,OAAA;AAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Q as Optional, a as Enumerator, p as OperatorSource } from "../core.js";
|
|
2
|
+
import { S as operator, _ as cachedTerminal, a as TyneqOrderedEnumerator, b as cachedOperator, c as createCachedTerminalOperator, d as createCachedOperator, g as createOperator, h as createGeneratorOperator, i as TyneqCachedEnumerator, l as createOrderedTerminalOperator, n as TyneqOrderedTerminalOperator, o as TyneqEnumerator, p as createOrderedOperator, r as TyneqTerminalOperator, s as TyneqBaseEnumerator, t as TyneqCachedTerminalOperator, u as createTerminalOperator, v as orderedTerminal, x as orderedOperator, y as terminal } from "../TyneqCachedTerminalOperator.js";
|
|
3
|
+
|
|
4
|
+
//#region src/plugin/decorators/source.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Options for the {@link source} decorator.
|
|
7
|
+
*/
|
|
8
|
+
interface SourceDecoratorOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The operator name used to look up this source in the registry.
|
|
11
|
+
* Must match the `operatorName` on the `QueryPlanNode`.
|
|
12
|
+
* Defaults to the decorated method's name when omitted.
|
|
13
|
+
*/
|
|
14
|
+
readonly name?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether this is a built-in (`"internal"`) or third-party (`"external"`) source.
|
|
17
|
+
* Defaults to `"external"`.
|
|
18
|
+
*/
|
|
19
|
+
readonly source?: OperatorSource;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Static method decorator that registers the decorated method as a source operator.
|
|
23
|
+
*
|
|
24
|
+
* The method itself becomes the factory: when the compiler resolves a source node
|
|
25
|
+
* whose `operatorName` matches the registered name, it calls the method with the
|
|
26
|
+
* node's `args`. No duplication of implementation - the registration points directly
|
|
27
|
+
* at the method.
|
|
28
|
+
*
|
|
29
|
+
* The operator name defaults to the method name, so `@source()` is sufficient when
|
|
30
|
+
* they match.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Optional config. Omit entirely to use all defaults.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { source } from "tyneq/plugin";
|
|
37
|
+
* import { Tyneq } from "tyneq";
|
|
38
|
+
*
|
|
39
|
+
* class MySources {
|
|
40
|
+
* @source()
|
|
41
|
+
* public static fibonacci(count: number): ReturnType<typeof Tyneq.range> {
|
|
42
|
+
* // registered as "fibonacci"
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* @source({ name: "fib2", source: "external" })
|
|
46
|
+
* public static fibonacci2(count: number): ReturnType<typeof Tyneq.range> {
|
|
47
|
+
* // registered as "fib2"
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @group Decorators
|
|
53
|
+
*/
|
|
54
|
+
declare function source(options?: SourceDecoratorOptions): <TMethod extends (...args: any[]) => any>(method: TMethod, context: ClassMethodDecoratorContext & {
|
|
55
|
+
static: true;
|
|
56
|
+
}) => void;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/utility/EnumeratorUtility.d.ts
|
|
59
|
+
/**
|
|
60
|
+
* Low-level helpers for working with `Enumerator<T>` objects inside custom operator enumerators.
|
|
61
|
+
*
|
|
62
|
+
* Import from `"tyneq/plugin"` when writing class-based operators that need to convert
|
|
63
|
+
* between `Iterable<T>` and `Enumerator<T>`, or that need safe cleanup via `tryDispose`.
|
|
64
|
+
*
|
|
65
|
+
* @group Plugin Utilities
|
|
66
|
+
*/
|
|
67
|
+
declare class EnumeratorUtility {
|
|
68
|
+
private constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Calls `enumerator.return()` if it exists, swallowing any error.
|
|
71
|
+
* Safe to call on `null` or `undefined`.
|
|
72
|
+
*/
|
|
73
|
+
static tryDispose<TSource>(enumerator: Optional<Enumerator<TSource>>): void;
|
|
74
|
+
/** Wraps an `Enumerator<T>` in a minimal `Iterable<T>` adapter (no buffering). */
|
|
75
|
+
static toIterable<TSource>(enumerator: Enumerator<TSource>): Iterable<TSource>;
|
|
76
|
+
/** Gets an `Enumerator<T>` from any `Iterable<T>`. */
|
|
77
|
+
static fromIterable<TSource>(iterable: Iterable<TSource>): Enumerator<TSource>;
|
|
78
|
+
/**
|
|
79
|
+
* Advances the enumerator by one position and returns `true` if that position was done.
|
|
80
|
+
*
|
|
81
|
+
* **Warning:** this calls `next()` and irrevocably consumes one element.
|
|
82
|
+
* If the enumerator is not exhausted, the yielded element is discarded.
|
|
83
|
+
* Only call this when advancing past the current position is intentional.
|
|
84
|
+
*/
|
|
85
|
+
static checkAndConsume<TSource>(enumerator: Enumerator<TSource>): boolean;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { EnumeratorUtility, TyneqBaseEnumerator, TyneqCachedEnumerator, TyneqCachedTerminalOperator, TyneqEnumerator, TyneqOrderedEnumerator, TyneqOrderedTerminalOperator, TyneqTerminalOperator, cachedOperator, cachedTerminal, createCachedOperator, createCachedTerminalOperator, createGeneratorOperator, createOperator, createOrderedOperator, createOrderedTerminalOperator, createTerminalOperator, operator, orderedOperator, orderedTerminal, source, terminal };
|
|
89
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/plugin/decorators/source.ts","../../src/utility/EnumeratorUtility.ts"],"mappings":";;;;;;;UAMiB,sBAAA;EAAsB;;;;;EAAA,SAM1B,IAAA;EAKuB;;AAoCpC;;EApCoC,SAAvB,MAAA,GAAS,cAAA;AAAA;;;;;;;;;;;;;;;;;;;ACNtB;;;;;;;;;;;;;;;iBD0CgB,MAAA,CAAO,OAAA,GAAS,sBAAA,wBACS,IAAA,iBACjC,MAAA,EAAQ,OAAA,EACR,OAAA,EAAS,2BAAA;EAAgC,MAAA;AAAA;;;;;AAlDjD;;;;;;cCKa,iBAAA;EAAA,QACF,WAAA,CAAA;EDKyB;AAoCpC;;;EApCoC,OCClB,UAAA,SAAA,CAAoB,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,OAAA;EDqCtD;EAAA,OC5BE,UAAA,SAAA,CAAoB,UAAA,EAAY,UAAA,CAAW,OAAA,IAAW,QAAA,CAAS,OAAA;ED6BrC;EAAA,OCtB1B,YAAA,SAAA,CAAsB,QAAA,EAAU,QAAA,CAAS,OAAA,IAAW,UAAA,CAAW,OAAA;EDmBjD;;;;;;;EAAA,OCRd,eAAA,SAAA,CAAyB,UAAA,EAAY,UAAA,CAAW,OAAA;AAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { E as TyneqTerminalOperator, F as TyneqBaseEnumerator, S as TyneqEnumerator, _ as operator, a as createCachedTerminalOperator, c as createCachedOperator, d as createOperator, f as cachedTerminal, g as orderedOperator, h as cachedOperator, i as TyneqOrderedEnumerator, l as createOrderedOperator, m as terminal, n as TyneqOrderedTerminalOperator, o as createOrderedTerminalOperator, p as orderedTerminal, r as TyneqCachedEnumerator, s as createTerminalOperator, t as TyneqCachedTerminalOperator, u as createGeneratorOperator, v as source, w as EnumeratorUtility } from "../TyneqCachedTerminalOperator.js";
|
|
2
|
+
export { EnumeratorUtility, TyneqBaseEnumerator, TyneqCachedEnumerator, TyneqCachedTerminalOperator, TyneqEnumerator, TyneqOrderedEnumerator, TyneqOrderedTerminalOperator, TyneqTerminalOperator, cachedOperator, cachedTerminal, createCachedOperator, createCachedTerminalOperator, createGeneratorOperator, createOperator, createOrderedOperator, createOrderedTerminalOperator, createTerminalOperator, operator, orderedOperator, orderedTerminal, source, terminal };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_Lazy = require("../Lazy.cjs");
|
|
3
|
+
const require_ValidationBuilder = require("../ValidationBuilder.cjs");
|
|
4
|
+
exports.ArgumentUtility = require_Lazy.ArgumentUtility;
|
|
5
|
+
exports.Lazy = require_Lazy.Lazy;
|
|
6
|
+
exports.ReflectionContext = require_Lazy.ReflectionContext;
|
|
7
|
+
exports.TypeGuardUtility = require_Lazy.TypeGuardUtility;
|
|
8
|
+
exports.ValidationBuilder = require_ValidationBuilder.ValidationBuilder;
|
|
9
|
+
exports.reflect = require_Lazy.reflect;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as reflect, c as MemberDescriptor, d as ArgumentUtility, i as ReflectionContext, l as MethodDescriptor, n as Lazy, o as AccessorDescriptor, r as TypeGuardUtility, s as DataDescriptor, t as ValidationBuilder, u as ReflectOptions } from "../ValidationBuilder.cjs";
|
|
2
|
+
export { type AccessorDescriptor, ArgumentUtility, type DataDescriptor, Lazy, type MemberDescriptor, type MethodDescriptor, type ReflectOptions, ReflectionContext, TypeGuardUtility, ValidationBuilder, reflect };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as reflect, c as MemberDescriptor, d as ArgumentUtility, i as ReflectionContext, l as MethodDescriptor, n as Lazy, o as AccessorDescriptor, r as TypeGuardUtility, s as DataDescriptor, t as ValidationBuilder, u as ReflectOptions } from "../ValidationBuilder.js";
|
|
2
|
+
export { type AccessorDescriptor, ArgumentUtility, type DataDescriptor, Lazy, type MemberDescriptor, type MethodDescriptor, type ReflectOptions, ReflectionContext, TypeGuardUtility, ValidationBuilder, reflect };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as ArgumentUtility, n as ReflectionContext, o as TypeGuardUtility, r as reflect, t as Lazy } from "../Lazy.js";
|
|
2
|
+
import { t as ValidationBuilder } from "../ValidationBuilder.js";
|
|
3
|
+
export { ArgumentUtility, Lazy, ReflectionContext, TypeGuardUtility, ValidationBuilder, reflect };
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tyneq",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lazy query pipelines for TypeScript.",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"./plugin": {
|
|
15
|
+
"types": "./dist/plugin/index.d.ts",
|
|
16
|
+
"import": "./dist/plugin/index.js",
|
|
17
|
+
"require": "./dist/plugin/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./utility": {
|
|
20
|
+
"types": "./dist/utility/index.d.ts",
|
|
21
|
+
"import": "./dist/utility/index.js",
|
|
22
|
+
"require": "./dist/utility/index.cjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc --noEmit && eslint src tests && tsdown",
|
|
32
|
+
"dev": "tsdown --watch",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest",
|
|
35
|
+
"test:coverage": "vitest run --coverage",
|
|
36
|
+
"docs:api": "typedoc --options typedoc.json",
|
|
37
|
+
"docs:api:full": "typedoc --options typedoc.dev.json",
|
|
38
|
+
"docs:dev": "npm run docs:api && vitepress dev docs",
|
|
39
|
+
"docs:build": "npm run docs:api && vitepress build docs",
|
|
40
|
+
"docs:build:pages": "npm run docs:api && vitepress build docs --base /tyneq/",
|
|
41
|
+
"docs:preview": "vitepress preview docs",
|
|
42
|
+
"docs:check": "npm run docs:build",
|
|
43
|
+
"docs:publish": "npm run docs:build:pages && gh-pages -d docs/.vitepress/dist -b gh-pages",
|
|
44
|
+
"lint": "eslint src tests",
|
|
45
|
+
"lint:fix": "eslint src tests --fix",
|
|
46
|
+
"prepublishOnly": "npm test && npm run build"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/chrisitopherus/tyneq.git"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"linq",
|
|
54
|
+
"linq-style",
|
|
55
|
+
"lazy",
|
|
56
|
+
"enumerable",
|
|
57
|
+
"sequence",
|
|
58
|
+
"query",
|
|
59
|
+
"query-builder",
|
|
60
|
+
"pipeline",
|
|
61
|
+
"iterator",
|
|
62
|
+
"streams",
|
|
63
|
+
"typescript"
|
|
64
|
+
],
|
|
65
|
+
"author": "chrisitopherus",
|
|
66
|
+
"license": "MIT",
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=20.19.0"
|
|
69
|
+
},
|
|
70
|
+
"sideEffects": [
|
|
71
|
+
"./dist/index.js",
|
|
72
|
+
"./dist/index.cjs"
|
|
73
|
+
],
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
},
|
|
77
|
+
"type": "module",
|
|
78
|
+
"bugs": {
|
|
79
|
+
"url": "https://github.com/chrisitopherus/tyneq/issues"
|
|
80
|
+
},
|
|
81
|
+
"homepage": "https://github.com/chrisitopherus/tyneq#readme",
|
|
82
|
+
"devDependencies": {
|
|
83
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
84
|
+
"eslint": "^10.0.3",
|
|
85
|
+
"gh-pages": "^6.3.0",
|
|
86
|
+
"jiti": "^2.6.1",
|
|
87
|
+
"tsdown": "^0.21.10",
|
|
88
|
+
"tsx": "^4.21.0",
|
|
89
|
+
"typedoc": "^0.28.13",
|
|
90
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
91
|
+
"typescript": "^5.9.3",
|
|
92
|
+
"typescript-eslint": "^8.57.0",
|
|
93
|
+
"vitepress": "^1.6.4",
|
|
94
|
+
"vitest": "^4.0.18"
|
|
95
|
+
}
|
|
96
|
+
}
|