@m4trix/core 0.5.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/README.md +72 -0
- package/dist/api/index.cjs +83 -0
- package/dist/api/index.cjs.map +1 -0
- package/dist/api/index.d.cts +74 -0
- package/dist/api/index.d.ts +74 -0
- package/dist/api/index.js +81 -0
- package/dist/api/index.js.map +1 -0
- package/dist/helper/index.cjs +253 -0
- package/dist/helper/index.cjs.map +1 -0
- package/dist/helper/index.d.cts +92 -0
- package/dist/helper/index.d.ts +92 -0
- package/dist/helper/index.js +251 -0
- package/dist/helper/index.js.map +1 -0
- package/dist/index.cjs +2670 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +2656 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +1324 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +213 -0
- package/dist/react/index.d.ts +213 -0
- package/dist/react/index.js +1316 -0
- package/dist/react/index.js.map +1 -0
- package/dist/stream/index.cjs +716 -0
- package/dist/stream/index.cjs.map +1 -0
- package/dist/stream/index.d.cts +304 -0
- package/dist/stream/index.d.ts +304 -0
- package/dist/stream/index.js +712 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/ui/index.cjs +316 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +30 -0
- package/dist/ui/index.d.ts +30 -0
- package/dist/ui/index.js +314 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/stream/Pump.ts","../../src/stream/utility/pipe-transformers/response.ts","../../src/stream/utility/rechunker/ensure-full-words.ts"],"names":["out","window"],"mappings":"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","sourcesContent":["/**\n * StreamChunk is the base interface for all streams.\n * It can hold voice and text chunks.\n *\n * @template T The type of data contained in the chunk\n */\nexport interface StreamChunk<T> {\n sequence: number;\n data: T;\n done: boolean;\n}\n\n/**\n * MessageStream represents an asynchronous iterable stream of chunks.\n * Used as the core stream representation throughout the Pump library.\n *\n * @template T The type of data contained in the chunks of the stream\n */\nexport type MessageStream<T> = AsyncIterable<StreamChunk<T>>;\n\n/**\n * Represents any source that can be converted to a stream.\n * This includes AsyncIterable and ReadableStream sources.\n *\n * @template T The type of data contained in the source\n */\nexport type Source<T> =\n | AsyncIterable<T>\n | ReadableStream<T>\n | NodeJS.ReadableStream;\n\n/**\n * A transformer for stream data that also provides a response.\n * Used primarily to transform and consume stream data while producing a response object.\n *\n * @template T The type of data being transformed\n * @template R The type of the response (defaults to Response)\n */\nexport type StreamTransformer<T, R = Response> = {\n transform(data: T): T;\n close(): void;\n response: R;\n};\n\n/**\n * Pump is an asynchronous stream processing pipeline with fluent operators.\n * It provides a comprehensive set of operations for transforming, filtering, batching,\n * combining, and consuming stream data.\n *\n * The Pump class follows a builder pattern where each operation returns a new Pump instance,\n * allowing for chaining of operations to build complex stream processing pipelines.\n *\n * @template T The type of data contained in the stream\n */\nexport class Pump<T> {\n constructor(private readonly src: MessageStream<T>) {}\n\n /**\n * Wrap an existing AsyncIterable or Readable stream into a Pump\n *\n * @template U The type of data in the source stream\n * @param source The source stream to convert to a Pump (AsyncIterable, ReadableStream, or NodeJS.ReadableStream)\n * @returns A new Pump instance that wraps the source\n */\n static from<U>(source: Source<U>): Pump<U> {\n async function* gen(): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n // Type guard functions to narrow the type\n function isAsyncIterable(obj: Source<U>): obj is AsyncIterable<U> {\n return Symbol.asyncIterator in obj;\n }\n\n function isWebReadableStream(obj: Source<U>): obj is ReadableStream {\n return 'getReader' in obj && typeof obj.getReader === 'function';\n }\n\n function isNodeReadableStream(\n obj: Source<U>\n ): obj is NodeJS.ReadableStream {\n return (\n 'pipe' in obj &&\n 'on' in obj &&\n typeof obj.pipe === 'function' &&\n typeof obj.on === 'function'\n );\n }\n\n if (isAsyncIterable(source)) {\n // Handle AsyncIterable\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (true) {\n const result = await iterator.next();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value,\n done: false,\n };\n }\n } finally {\n // No need to clean up AsyncIterator\n }\n } else if (isWebReadableStream(source)) {\n // Handle Web API ReadableStream\n const reader = source.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n yield {\n sequence: seq++,\n data: result.value as U,\n done: false,\n };\n }\n } finally {\n reader.releaseLock();\n }\n } else if (isNodeReadableStream(source)) {\n // Handle Node.js ReadableStream\n try {\n // Convert Node stream to an AsyncIterable\n for await (const chunk of source) {\n yield {\n sequence: seq++,\n data: chunk as U,\n done: false,\n };\n }\n } catch (error) {\n console.error('Error reading from Node.js stream:', error);\n throw error;\n }\n }\n\n // final done signal\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen()) as Pump<U>;\n }\n\n /**\n * Sync or async map over the data portion of each chunk\n *\n * @template U The output type after transformation\n * @param fn The mapping function that transforms each chunk\n * @returns A new Pump instance with the transformed data\n */\n map<U>(fn: (data: T) => U | Promise<U>): Pump<U> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<U>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n const out = data !== undefined ? await fn(data) : undefined;\n yield { sequence, data: out as unknown as U, done };\n break;\n }\n\n const out = await fn(data);\n yield { sequence, data: out, done };\n }\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Stateful map allows processing stream chunks with a persistent context object.\n *\n * The context is initialized when the first chunk arrives and can be updated with each chunk.\n * This is useful for maintaining state across the stream processing.\n *\n * If you plan to use sockets you should rather opt for asyncStatefulMap.\n *\n * The pipe closes only after all processing is complete, including any final operations in onClose.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n statefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n\n // <- here ->\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(lastChunk, context, yieldData);\n }\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(data, yieldData);\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(data, context, yieldData);\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Async map means that each incoming chunk is causing an async operation that when it completes\n * should yield a new chunk.\n * The pipe closes only after you unlock the pipe by using the unlockCloseEvent callback.\n *\n * Stateful refers to the fact that you can create your own small context object that is passed in the subsequent callbacks.\n * This allows you to keep track of things like a socket connection.\n *\n * Why is this nice? Well if you use things like a socket the pipe might have received the close event,\n * before you got any or all of your socket responses. Sockets don't fit into the standard promise pattern,\n * which makes it harder to wait for them.\n *\n * TODO: Un-tested\n *\n * @param handlers Object containing callback functions for stream processing\n * @param handlers.onFirstChunk Function called when the first chunk arrives, initializes the context\n * @param handlers.onChunk Function called for each subsequent chunk, updates the context\n * @param handlers.onClose Optional function called when the stream closes, allows final processing\n * @returns A new Pump instance with transformed data\n */\n asyncStatefulMap<Context, U = T>(handlers: {\n onFirstChunk(\n chunk: T,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onChunk(\n chunk: T,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): Context | Promise<Context>;\n onClose?(\n lastChunk: T | undefined,\n context: Context,\n yieldData: (data: U) => void,\n unlockCloseEvent: () => void\n ): void | Promise<void>;\n }): Pump<U> {\n const { src } = this;\n\n const gen = async function* (): AsyncGenerator<StreamChunk<U>> {\n let context: Context | undefined;\n let initialized = false;\n let lastChunk: T | undefined;\n let seq = 0;\n let lockedCloseEvent = true;\n\n const queue: U[] = [];\n const yieldData = (data: U): void => {\n queue.push(data);\n };\n const unlockCloseEvent = (): void => {\n lockedCloseEvent = false;\n };\n\n for await (const { data, done } of src) {\n if (done) {\n if (context && handlers.onClose) {\n await handlers.onClose(\n lastChunk,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n const timestamp = Date.now();\n // wait until the pipe is unlocked\n while (lockedCloseEvent && Date.now() - timestamp < 10_000) {\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n // put on top of event loop / call stack\n await new Promise((resolve) => setTimeout(resolve, 5));\n }\n\n // First emit all data in the queue\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n\n yield {\n sequence: seq++,\n data: undefined as unknown as U,\n done: true,\n };\n break;\n }\n if (!initialized) {\n context = await handlers.onFirstChunk(\n data,\n yieldData,\n unlockCloseEvent\n );\n initialized = true;\n } else if (context) {\n context = await handlers.onChunk(\n data,\n context,\n yieldData,\n unlockCloseEvent\n );\n }\n\n lastChunk = data;\n\n while (queue.length > 0) {\n yield { sequence: seq++, data: queue.shift()!, done: false };\n }\n }\n };\n\n return new Pump<U>(gen());\n }\n\n /**\n * Filter items based on a predicate\n *\n * @param predicate A function that determines whether to keep each chunk\n * @returns A new Pump instance containing only chunks that passed the predicate\n */\n filter(predicate: (data: T) => boolean | Promise<boolean>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n yield { sequence, data, done: true };\n break;\n }\n\n const keep = await predicate(data);\n if (keep) {\n yield { sequence, data, done: false };\n }\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Bundles (accumulates) chunks together based on a condition rather than a fixed size.\n *\n * This is useful when you need to group chunks dynamically based on their content or other criteria.\n *\n * Example: Bundling text chunks with a maximum character limit\n *\n * Input chunks: [\"Hello\", \" this\", \" is\", \" a few\", \" chunks\", \" of text\"]\n * With max size of 10 characters:\n * - First bundle: [\"Hello\", \" this\"] (10 chars)\n * - Second bundle: [\" is\", \" a few\"] (8 chars)\n * - Third bundle: [\" chunks\", \" of text\"] (13 chars)\n *\n * @param closeBundleCondition - Function that determines when to close the current bundle\n * Returns true when the current bundle should be emitted\n * Parameters:\n * - chunk: The current chunk being processed\n * - accumulatedChunks: Array of chunks in the current bundle\n *\n * @returns A pump that emits arrays of bundled items\n */\n bundle(\n closeBundleCondition: (\n chunk: T,\n accumulatedChunks: Array<T>\n ) => boolean | Promise<boolean>\n ): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: Array<T> = [];\n let lastSequence = 0;\n\n for await (const { sequence, data, done } of this.src) {\n lastSequence = sequence;\n\n if (done) {\n // Emit any remaining items in the buffer when the stream ends\n if (buffer.length > 0) {\n yield { sequence, data: [...buffer], done: false };\n }\n // Emit the termination signal\n yield {\n sequence: lastSequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n break;\n }\n\n const shouldClose = await closeBundleCondition(data, buffer);\n buffer.push(data);\n\n if (shouldClose) {\n yield {\n sequence: lastSequence,\n data: [...buffer],\n done: false,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * Tap into each chunk without altering it\n *\n * @param fn A function that receives each chunk but doesn't affect the stream\n * @returns The same pump instance with unmodified data\n */\n onChunk(fn: (chunk: T) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n for await (const chunk of this.src) {\n if (chunk.data === undefined && chunk.done) {\n // Yield early since we don't need to tap into a closing signal (unless it contains data)\n yield chunk;\n }\n\n await fn(chunk.data);\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Collect all chunks in the stream and run a callback when the stream is done.\n * The callback receives an array of all chunks that passed through.\n *\n * This is useful for analytics, logging, or processing the complete stream history\n * after all chunks have been received.\n *\n * @param fn - Callback function that receives the array of all chunks when the stream is complete\n * @returns The same pump, for chaining\n */\n onClose(fn: (history: T[]) => void | Promise<void>): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n const history: T[] = [];\n\n for await (const chunk of this.src) {\n // Add non-done chunks to history\n if (chunk.data !== undefined) {\n history.push(chunk.data);\n }\n\n // If we've reached the end, run the callback\n if (chunk.done) {\n await fn(history);\n }\n\n // Pass through the chunk unchanged\n yield chunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Batch `n` chunks into arrays before emitting\n *\n * @param n The number of chunks to batch together\n * @returns A new Pump instance that emits arrays of batched chunks\n */\n batch(n: number): Pump<Array<T>> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<Array<T>>> {\n let buffer: StreamChunk<T>[] = [];\n\n for await (const chunk of this.src) {\n if (chunk.done) {\n // Termination signal edge case handling\n if (chunk.data === undefined) {\n // Flush the rest\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: false,\n };\n\n // and then emit the termination signal\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n buffer = [];\n } else {\n // in that case the termination signal contains data\n // so we need to emit this as a closing singal with the rest of the buffer\n buffer.push(chunk);\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: true,\n };\n }\n\n break;\n }\n\n // Normal case\n\n buffer.push(chunk);\n\n if (buffer.length === n) {\n yield {\n sequence: buffer[0].sequence,\n data: buffer.map((c) => c.data),\n done: chunk.done,\n };\n buffer = [];\n }\n }\n }\n return new Pump<Array<T>>(gen.call(this));\n }\n\n /**\n * If you want to prevent chunk starvation, you can buffer the chunks.\n * Chunks will not be bundled into arrays or object but kept as is,\n * but the pipeline will not progress at that segment until the buffer is filled up.\n * Once a buffer is filled up it will drain and never buffer again.\n *\n * @param n The number of chunks to buffer before processing continues\n * @returns A new Pump instance with buffering behavior\n */\n buffer(n: number): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: StreamChunk<T>[] = [];\n let bufferFilled = false;\n\n for await (const chunk of this.src) {\n if (!bufferFilled) {\n if (!chunk.done) {\n buffer.push(chunk);\n }\n\n // If buffer is filled or we've reached the end of the stream\n if (buffer.length >= n || chunk.done) {\n bufferFilled = true;\n // Yield all buffered chunks\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n if (chunk.done) {\n yield {\n sequence: chunk.sequence,\n data: undefined as unknown as T,\n done: true,\n };\n break;\n }\n buffer = [];\n }\n } else {\n // After buffer is filled, just pass chunks through\n yield chunk;\n }\n }\n\n // Yield any remaining chunks in the buffer\n for (const bufferedChunk of buffer) {\n yield bufferedChunk;\n }\n }\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Rechunk the stream: transform one chunk into zero, one, or many output chunks.\n * The handler function receives the current buffer of chunks, a push function to emit new chunks,\n * and a flag indicating if this is the last chunk in the stream.\n *\n * @param handler Function that transforms chunks and pushes new ones\n * @returns A new Pump instance with rechunked data\n */\n rechunk(\n handler: (params: {\n buffer: T[];\n push: (chunk: T) => void;\n lastChunk: boolean;\n setBuffer: (buffer: T[]) => void;\n }) => void | Promise<void>\n ): Pump<T> {\n async function* gen(this: Pump<T>): AsyncGenerator<StreamChunk<T>> {\n let buffer: Array<T> = [];\n let seq = 0;\n const pending: Array<T> = [];\n\n const push = (chunk: T): void => {\n pending.push(chunk);\n };\n\n for await (const { data, done } of this.src) {\n if (!done) {\n if (data !== undefined) {\n buffer.push(data);\n }\n await handler({\n buffer,\n push,\n lastChunk: false,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n } else {\n await handler({\n buffer,\n push,\n lastChunk: true,\n setBuffer: (b: T[]) => {\n buffer = b;\n },\n });\n }\n\n while (pending.length > 0) {\n const out = pending.shift()!;\n yield { sequence: seq++, data: out, done: false };\n }\n\n if (done) {\n break;\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as T, done: true };\n }\n\n return new Pump<T>(gen.call(this));\n }\n\n /**\n * Emit sliding windows of the last `size` items with step `step`.\n * Each window is an array [current, previous1, ..., previous(size-1)].\n * Optionally, map each window through a function.\n *\n * | Step | Window | Resulting Window |\n * |------|--------|------------------|\n * | 1 | ▪︎▪︎[▪︎▫︎▫︎] | ▪︎▫︎▫︎ |\n * | 2 | ▪︎[▪︎▪︎▫︎] | ▪︎▪︎▫︎ |\n * | 3 | [▪︎▪︎▪︎] | ▪︎▪︎▪︎ |\n * | 4 | [▫︎▪︎▪︎] | ▫︎▪︎▪︎ |\n * | 5 | [▫︎▫︎▪︎] | ▫︎▫︎▪ |\n *\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @returns A Pump that emits arrays representing sliding windows\n */\n slidingWindow(size: number, step: number): Pump<Array<T | undefined>>;\n /**\n * Emit sliding windows of the last `size` items with step `step`,\n * and map each window using the provided function.\n *\n * @template N The size type parameter (extends number)\n * @template U The output type after window transformation\n * @param size The size of each window\n * @param step The number of items to move between windows\n * @param fn A function to transform each window\n * @returns A Pump that emits transformed sliding windows\n */\n slidingWindow<N extends number, U>(\n size: N,\n step: number,\n fn: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<U>;\n slidingWindow<U>(\n size: number,\n step: number,\n fn?: (window: Array<T | undefined>) => U | Promise<U>\n ): Pump<Array<T | undefined>> | Pump<U> {\n async function* gen(\n this: Pump<T>\n ): AsyncGenerator<StreamChunk<Array<T | undefined>>> {\n const history: Array<T> = [];\n let offset = 0;\n let lastSeq = 0;\n\n function buildWindow(\n _offset: number,\n _size: number,\n _history: Array<T>\n ): Array<T | undefined> {\n const window: Array<T | undefined> = Array(_size).fill(undefined);\n let windowIndex = 0;\n\n for (let i = _offset; i > _offset - _size; i -= step) {\n if (i >= history.length) {\n windowIndex++;\n // we can skip this since we are filling the blank spots with undefined\n continue;\n }\n\n if (i < 0) {\n break;\n }\n\n window[windowIndex] = _history[i]; // the window follows the analoy so its filled reversed from the graphic\n windowIndex++;\n }\n\n return window;\n }\n\n for await (const { sequence, data, done } of this.src) {\n if (done) {\n // if we are done that means we are not receiving any more signals to push the window\n // so we have to emit the last window steps\n // [▪︎▪︎▫︎]\n // [▪︎▫︎▫︎]\n for (let i = 0; i < size - 1; i++) {\n const window = buildWindow(offset + i, size, history);\n yield { sequence: lastSeq, data: window, done: false };\n }\n\n if (data === undefined) {\n // final done signal\n yield {\n sequence: lastSeq,\n data: undefined as unknown as Array<T>,\n done: true,\n };\n } else {\n // final done signal\n yield {\n sequence: lastSeq,\n data: [\n history[history.length - 2] ?? undefined,\n history[history.length - 3] ?? undefined,\n history[history.length - 1],\n ],\n done: true,\n };\n }\n break;\n }\n\n lastSeq = sequence;\n history.push(data);\n\n // the rolling window goes from the oldest to the newest and pushes it self\n // with a step length. The analogy of the pipe shifts the window from right to left\n // but the array appends to the end. So in this implementation we are shifting from left to right.\n\n // lets calculate the window indexes\n // [▫︎▫︎▪︎]▪︎▪︎\n // [▫︎▪︎▪︎]▪︎\n // [▪︎▪︎▪︎]\n // [▪︎▪︎▫︎] <- this case is handled above\n // [▪︎▫︎▫︎] <- this case is handled above\n const window = buildWindow(offset, size, history);\n\n yield { sequence, data: window, done: false };\n offset++;\n }\n }\n const base = new Pump<Array<T | undefined>>(gen.call(this));\n // If fn is provided, map over the window, otherwise return the window as is\n return fn\n ? base.map(fn as (window: Array<T | undefined>) => U)\n : (base as Pump<Array<T | undefined>>);\n }\n\n /**\n * Sequentially flatten inner stream sources emitted by the pipeline.\n * Works with any Source type (AsyncIterable or ReadableStream).\n * This method is only available when the current Pump contains Source elements.\n *\n * @template U The type of data in the inner streams\n * @template F The type of inner stream source (extends Source<U>)\n * @returns A Pump instance with flattened stream data\n */\n sequenceStreams<U, F extends Source<U>>(this: Pump<F>): Pump<U> {\n async function* gen(this: Pump<F>): AsyncGenerator<StreamChunk<U>> {\n let seq = 0;\n\n for await (const { data: innerSource, done: outerDone } of this.src) {\n if (outerDone) break;\n\n // Convert the inner source to a pump first\n const innerPump = Pump.from(innerSource as unknown as Source<U>);\n\n // Then extract all items from it\n for await (const { data, done } of innerPump.src) {\n if (done) break;\n yield { sequence: seq++, data: data as U, done: false };\n }\n }\n\n yield { sequence: seq, data: undefined as unknown as U, done: true };\n }\n return new Pump<U>(gen.call(this));\n }\n\n /**\n * Fork the stream: two independent Pump<T> consumers\n * Both resulting Pumps will receive the same data, allowing for divergent processing paths.\n *\n * @returns An array containing two independent Pump instances with the same source data\n */\n fork(): [Pump<T>, Pump<T>] {\n const buffers: StreamChunk<T>[][] = [[], []];\n let done = false;\n const srcIter = this.src[Symbol.asyncIterator]();\n\n async function fill(): Promise<void> {\n const { value, done: streamDone } = await srcIter.next();\n if (streamDone) {\n done = true;\n return;\n }\n buffers.forEach((q) => q.push(value));\n if (value.done) done = true;\n }\n\n function makeStream(buf: StreamChunk<T>[]): MessageStream<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<StreamChunk<T>> {\n return {\n async next(): Promise<IteratorResult<StreamChunk<T>>> {\n while (buf.length === 0 && !done) {\n await fill();\n }\n if (buf.length === 0)\n return {\n done: true,\n value: undefined as unknown as StreamChunk<T>,\n };\n return { done: false, value: buf.shift()! };\n },\n };\n },\n };\n }\n\n return [new Pump(makeStream(buffers[0])), new Pump(makeStream(buffers[1]))];\n }\n\n /**\n * Drain the pipeline, consuming all chunks.\n * Returns a Promise that resolves when all chunks have been consumed.\n *\n * @returns A Promise that resolves when all chunks have been consumed\n */\n drain(): Promise<void> {\n return (async (): Promise<void> => {\n for await (const { done } of this.src) {\n if (done) break;\n }\n })();\n }\n\n /**\n * Drain the pipeline to a StreamTransformer.\n * Applies transform() to each data chunk, then closes the transformer,\n * and returns its response (which can be of any type defined by the transformer).\n *\n * Example with httpStreamResponse:\n * ```\n * const { transform, response, close } = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo({ transform, close, response });\n * ```\n *\n * @template U The type of data expected by the transformer (extends T)\n * @template R The response type produced by the transformer\n * @param transformer The StreamTransformer to drain to\n * @returns The response from the transformer\n */\n drainTo<U extends T, R>(transformer: StreamTransformer<U, R>): R {\n (async (): Promise<void> => {\n for await (const { data, done } of this.src) {\n if (done) break;\n transformer.transform(data as unknown as U);\n }\n transformer.close();\n })();\n return transformer.response;\n }\n}\n\n// ----------------------------------------------------------\n// Example usage in Next.js App Router (e.g. app/api/stream/route.ts)\n//\n// import { NextRequest } from 'next/server';\n// import { Pump } from '@m4trix/core/stream';\n// import { /*...*/ } from '@/lib';\n\n// export async function POST(req: NextRequest) {\n// // Process the incoming audio request\n// const formData = await req.formData();\n// const transcript = await transcribeFormData(formData);\n// const agentStream = await getAgentResponse(transcript);\n\n// // Process and return the stream\n// return await Pump.from(agentStream)\n// .filter(shouldChunkBeStreamed)\n// .map(messageToText)\n// .bundle(intoChunksOfMinLength(40))\n// .map((text) => text.join(\"\")) // convert array of strings to string\n// .rechunk(ensureFullWords)\n// .rechunk(fixBrokenWords)\n// .onClose(handleCompletedAgentResponse)\n// .slidingWindow(10, 1)\n// .filter(filterOutIrrelevantWindows)\n// .buffer(5)\n// .map(textToSpeech)\n// .sequenceStreams()\n// .drainTo(httpStreamResponse());\n// }\n","import { StreamTransformer } from '../..';\n\nexport interface HttpStreamOptions<T> {\n /** HTTP ResponseInit (status, headers, etc.) */\n init?: ResponseInit;\n /** Encode each chunk of type T into bytes or string */\n encoder?: (data: T) => Uint8Array | string;\n}\n\n/**\n * Create a streaming HTTP response transformer.\n * Returns an object with:\n * - transform: function to write each chunk into the response\n * - response: the Fetch API Response ready to return\n * - close: function to close the stream when done\n *\n * Usage in a Next.js route:\n * ```\n * // With the new drainTo API:\n * const transformer = httpStreamResponse(options);\n * return Pump.from(messageStream).drainTo(transformer);\n *\n * // Or with manual control:\n * const { transform, response, close } = httpStreamResponse(options);\n * await Pump.from(messageStream).map(transform).drain();\n * close();\n * return response;\n * ```\n */\nexport function httpStreamResponse<T>(\n options: HttpStreamOptions<T> = {}\n): StreamTransformer<T, Response> {\n const { init, encoder } = options;\n const encodeFn =\n encoder ??\n ((d: T): Uint8Array | string => {\n if (d instanceof Uint8Array) return d;\n if (typeof d === 'string') return d;\n return JSON.stringify(d);\n });\n\n // Create a transform stream of Uint8Array\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const response = new Response(readable, init);\n\n const transform = (chunk: T): T => {\n const encoded = encodeFn(chunk);\n const bytes =\n typeof encoded === 'string' ? new TextEncoder().encode(encoded) : encoded;\n writer.write(bytes);\n return chunk;\n };\n\n const close = (): void => {\n writer.close();\n };\n\n return { transform, response, close };\n}\n","/**\n * A helper to be used with Pump.rechunk that ensures full word chunks.\n * Aggregates incoming chunks and emits only when a full word boundary is reached.\n */\nexport async function ensureFullWords({\n buffer,\n push,\n lastChunk,\n}: {\n buffer: string[];\n push: (chunk: string) => void;\n lastChunk: boolean;\n}): Promise<void> {\n const combined = buffer.join('');\n const lastBoundary = Math.max(\n combined.lastIndexOf(' '),\n combined.lastIndexOf('\\n'),\n combined.lastIndexOf('\\t')\n );\n\n if (lastBoundary !== -1 || lastChunk) {\n const emitPart =\n lastBoundary !== -1 ? combined.slice(0, lastBoundary + 1) : combined;\n const leftoverPart =\n lastBoundary !== -1 ? combined.slice(lastBoundary + 1) : '';\n\n if (emitPart.trim().length > 0) {\n push(emitPart);\n }\n\n buffer.length = 0;\n if (leftoverPart.length > 0) {\n buffer.push(leftoverPart);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lit = require('lit');
|
|
4
|
+
var decorators_js = require('lit/decorators.js');
|
|
5
|
+
var ref_js = require('lit/directives/ref.js');
|
|
6
|
+
var animejs = require('animejs');
|
|
7
|
+
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
11
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
12
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
13
|
+
if (decorator = decorators[i])
|
|
14
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
15
|
+
if (kind && result)
|
|
16
|
+
__defProp(target, key, result);
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
var AiCursorComponentStyle = lit.css`
|
|
20
|
+
:host {
|
|
21
|
+
--ai-local-cursor-size: var(--sk-ai-cursor-size, 1rem);
|
|
22
|
+
--ai-local-cursor-label-padding: var(
|
|
23
|
+
--sk-ai-cursor-label-padding,
|
|
24
|
+
0.25rem 0.25rem
|
|
25
|
+
);
|
|
26
|
+
--ai-local-cursor-border-radius: var(--sk-ai-cursor-border-radius, 0.25rem);
|
|
27
|
+
--ai-local-label-offset: var(--sk-ai-cursor-label-offset, 1rem);
|
|
28
|
+
|
|
29
|
+
--ai-local-label-font-size: var(--sk-ai-cursor-label-font-size, 12px);
|
|
30
|
+
--ai-local-label-font-weight: var(--sk-ai-cursor-label-font-weight, bold);
|
|
31
|
+
--ai-local-label-color: var(--sk-ai-cursor-label-color, white);
|
|
32
|
+
--ai-local-label-background-color: var(
|
|
33
|
+
--sk-ai-cursor-label-background-color,
|
|
34
|
+
black
|
|
35
|
+
);
|
|
36
|
+
--ai-local-label-border-color: var(
|
|
37
|
+
--sk-ai-cursor-label-border-color,
|
|
38
|
+
white
|
|
39
|
+
);
|
|
40
|
+
--ai-local-label-border-width: var(
|
|
41
|
+
--sk-ai-cursor-label-border-width,
|
|
42
|
+
0.1rem
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
color: black;
|
|
46
|
+
stroke: white;
|
|
47
|
+
position: absolute;
|
|
48
|
+
/* Insetting in the parent element (body) */
|
|
49
|
+
top: 0;
|
|
50
|
+
left: 0;
|
|
51
|
+
bottom: 0;
|
|
52
|
+
right: 0;
|
|
53
|
+
pointer-events: none;
|
|
54
|
+
width: var(--ai-local-cursor-size);
|
|
55
|
+
height: var(--ai-local-cursor-size);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#cursor-graphic-parent {
|
|
59
|
+
position: absolute;
|
|
60
|
+
top: 0;
|
|
61
|
+
left: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#label-text {
|
|
65
|
+
position: absolute;
|
|
66
|
+
color: white;
|
|
67
|
+
font-size: 12px;
|
|
68
|
+
font-weight: bold;
|
|
69
|
+
padding: var(--ai-local-cursor-label-padding);
|
|
70
|
+
border-radius: var(--ai-local-cursor-border-radius);
|
|
71
|
+
|
|
72
|
+
white-space: nowrap;
|
|
73
|
+
overflow: hidden;
|
|
74
|
+
text-overflow: ellipsis;
|
|
75
|
+
|
|
76
|
+
width: fit-content;
|
|
77
|
+
min-width: fit-content;
|
|
78
|
+
top: var(--ai-local-label-offset);
|
|
79
|
+
left: var(--ai-local-label-offset);
|
|
80
|
+
|
|
81
|
+
border: var(--ai-local-label-border-width) solid
|
|
82
|
+
var(--ai-local-label-border-color);
|
|
83
|
+
background-color: var(--ai-local-label-background-color);
|
|
84
|
+
color: var(--ai-local-label-color);
|
|
85
|
+
font-size: var(--ai-local-label-font-size);
|
|
86
|
+
font-weight: var(--ai-local-label-font-weight);
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
// src/ui/ai-cursor/rendering/AiCursorComponent.ts
|
|
91
|
+
var AiCursorComponent = class extends lit.LitElement {
|
|
92
|
+
constructor() {
|
|
93
|
+
super();
|
|
94
|
+
this.eventHooks = {
|
|
95
|
+
defineSetPosition: () => {
|
|
96
|
+
},
|
|
97
|
+
defineAddPositionToQueue: () => {
|
|
98
|
+
},
|
|
99
|
+
definePlayQueue: () => {
|
|
100
|
+
},
|
|
101
|
+
defineSetShowCursor: () => {
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
this.isShowingCursor = true;
|
|
105
|
+
this.labelText = "AI Cursor";
|
|
106
|
+
this.cursorPosition = [0, 0];
|
|
107
|
+
this._cursorRef = ref_js.createRef();
|
|
108
|
+
this._labelRef = ref_js.createRef();
|
|
109
|
+
}
|
|
110
|
+
updated(_changedProperties) {
|
|
111
|
+
if (_changedProperties.has("_cursorRef")) {
|
|
112
|
+
if (this._cursorRef.value) {
|
|
113
|
+
this.hookUpCallbacks();
|
|
114
|
+
} else {
|
|
115
|
+
this._timeline?.pause();
|
|
116
|
+
this._timeline?.refresh();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
super.updated(_changedProperties);
|
|
120
|
+
}
|
|
121
|
+
render() {
|
|
122
|
+
const cursorSvg = lit.html`
|
|
123
|
+
<svg
|
|
124
|
+
width=${24}
|
|
125
|
+
height=${24}
|
|
126
|
+
viewBox="0 0 100 100"
|
|
127
|
+
fill="none"
|
|
128
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
129
|
+
>
|
|
130
|
+
<g clip-path="url(#clip0_3576_285)">
|
|
131
|
+
<path
|
|
132
|
+
class="cursor-path"
|
|
133
|
+
d="M2.14849 7.04749C1.35153 4.07321 4.07319 1.35155 7.04747 2.14851L77.3148 20.9766C80.2891 21.7735 81.2853 25.4914 79.108 27.6687L27.6687 79.108C25.4914 81.2853 21.7735 80.2891 20.9766 77.3149L2.14849 7.04749Z"
|
|
134
|
+
fill="currentColor"
|
|
135
|
+
/>
|
|
136
|
+
</g>
|
|
137
|
+
<defs>
|
|
138
|
+
<clipPath id="clip0_3576_285">
|
|
139
|
+
<rect width="100" height="100" fill="white" />
|
|
140
|
+
</clipPath>
|
|
141
|
+
</defs>
|
|
142
|
+
</svg>
|
|
143
|
+
`;
|
|
144
|
+
return lit.html`
|
|
145
|
+
<span
|
|
146
|
+
id="cursor-graphic-parent"
|
|
147
|
+
${ref_js.ref(this._cursorRef)}
|
|
148
|
+
?hidden=${!this.isShowingCursor}
|
|
149
|
+
>
|
|
150
|
+
${cursorSvg}
|
|
151
|
+
<span
|
|
152
|
+
${ref_js.ref(this._labelRef)}
|
|
153
|
+
id="label-text"
|
|
154
|
+
?hidden=${!this.isShowingCursor}
|
|
155
|
+
>${this.labelText}</span
|
|
156
|
+
>
|
|
157
|
+
</span>
|
|
158
|
+
`;
|
|
159
|
+
}
|
|
160
|
+
// private methods
|
|
161
|
+
/**
|
|
162
|
+
* The primary way to control the cursor is using an external API.
|
|
163
|
+
* This interface exposes controlling methods. The Lit Component itself is
|
|
164
|
+
* intended to be a controlled component.
|
|
165
|
+
*/
|
|
166
|
+
hookUpCallbacks() {
|
|
167
|
+
const animationTarget = this._cursorRef.value;
|
|
168
|
+
if (!animationTarget) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
this._timeline = animejs.createTimeline({ defaults: { duration: 750 } });
|
|
172
|
+
if (!this._timeline) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.eventHooks.defineSetPosition((position) => {
|
|
176
|
+
this._timeline?.add(animationTarget, {
|
|
177
|
+
translateX: position[0],
|
|
178
|
+
translateY: position[1],
|
|
179
|
+
duration: 1
|
|
180
|
+
});
|
|
181
|
+
this._timeline?.play();
|
|
182
|
+
});
|
|
183
|
+
this.eventHooks.defineAddPositionToQueue((position) => {
|
|
184
|
+
this._timeline?.add(animationTarget, {
|
|
185
|
+
translateX: position[0],
|
|
186
|
+
translateY: position[1],
|
|
187
|
+
duration: 1e3
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
this.eventHooks.defineSetShowCursor((show) => {
|
|
191
|
+
this.isShowingCursor = show;
|
|
192
|
+
});
|
|
193
|
+
this.eventHooks.definePlayQueue(() => {
|
|
194
|
+
this._timeline?.play();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Getters
|
|
198
|
+
get cursorRef() {
|
|
199
|
+
return this._cursorRef.value;
|
|
200
|
+
}
|
|
201
|
+
get labelRef() {
|
|
202
|
+
return this._labelRef.value;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
// Define scoped styles right with your component, in plain CSS
|
|
206
|
+
AiCursorComponent.styles = AiCursorComponentStyle;
|
|
207
|
+
__decorateClass([
|
|
208
|
+
decorators_js.property({
|
|
209
|
+
type: Object
|
|
210
|
+
})
|
|
211
|
+
], AiCursorComponent.prototype, "eventHooks", 2);
|
|
212
|
+
__decorateClass([
|
|
213
|
+
decorators_js.property({ type: Boolean })
|
|
214
|
+
], AiCursorComponent.prototype, "isShowingCursor", 2);
|
|
215
|
+
__decorateClass([
|
|
216
|
+
decorators_js.property({ type: String })
|
|
217
|
+
], AiCursorComponent.prototype, "labelText", 2);
|
|
218
|
+
__decorateClass([
|
|
219
|
+
decorators_js.property({ type: Array })
|
|
220
|
+
], AiCursorComponent.prototype, "cursorPosition", 2);
|
|
221
|
+
__decorateClass([
|
|
222
|
+
decorators_js.state()
|
|
223
|
+
], AiCursorComponent.prototype, "_cursorRef", 2);
|
|
224
|
+
__decorateClass([
|
|
225
|
+
decorators_js.state()
|
|
226
|
+
], AiCursorComponent.prototype, "_labelRef", 2);
|
|
227
|
+
AiCursorComponent = __decorateClass([
|
|
228
|
+
decorators_js.customElement("ai-cursor")
|
|
229
|
+
], AiCursorComponent);
|
|
230
|
+
|
|
231
|
+
// src/ui/ai-cursor/rendering/index.ts
|
|
232
|
+
var mountAiCursor = (aiCursorProps) => {
|
|
233
|
+
const root = document.body;
|
|
234
|
+
const cursor = document.createElement("ai-cursor");
|
|
235
|
+
cursor.eventHooks = aiCursorProps.eventHooks;
|
|
236
|
+
root.appendChild(cursor);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// src/ui/ai-cursor/AiCursor.ts
|
|
240
|
+
var AiCursor = class _AiCursor {
|
|
241
|
+
constructor() {
|
|
242
|
+
}
|
|
243
|
+
// Static constructors
|
|
244
|
+
static spawn() {
|
|
245
|
+
const newCursor = new _AiCursor();
|
|
246
|
+
newCursor.mount();
|
|
247
|
+
return newCursor;
|
|
248
|
+
}
|
|
249
|
+
jumpTo(target) {
|
|
250
|
+
const position = targetToPosition(target);
|
|
251
|
+
if (position) {
|
|
252
|
+
this.setPosition?.(position);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
moveTo(target) {
|
|
256
|
+
const position = targetToPosition(target);
|
|
257
|
+
if (position) {
|
|
258
|
+
this.addPositionToQueue?.(position);
|
|
259
|
+
this.playQueue?.();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
scheduleMoves(targets) {
|
|
263
|
+
targets.forEach((target) => {
|
|
264
|
+
const position = targetToPosition(target);
|
|
265
|
+
if (position) {
|
|
266
|
+
this.addPositionToQueue?.(position);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
this.playQueue?.();
|
|
270
|
+
}
|
|
271
|
+
show() {
|
|
272
|
+
this.setShowCursor?.(true);
|
|
273
|
+
}
|
|
274
|
+
hide() {
|
|
275
|
+
this.setShowCursor?.(false);
|
|
276
|
+
}
|
|
277
|
+
mount() {
|
|
278
|
+
mountAiCursor({
|
|
279
|
+
eventHooks: {
|
|
280
|
+
defineSetPosition: (callback) => {
|
|
281
|
+
this.setPosition = callback;
|
|
282
|
+
},
|
|
283
|
+
defineAddPositionToQueue: (callback) => {
|
|
284
|
+
this.addPositionToQueue = callback;
|
|
285
|
+
},
|
|
286
|
+
definePlayQueue: (callback) => {
|
|
287
|
+
this.playQueue = callback;
|
|
288
|
+
},
|
|
289
|
+
defineSetShowCursor: (callback) => {
|
|
290
|
+
this.setShowCursor = callback;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
function calculateClickPositionFromElement(element) {
|
|
297
|
+
const rect = element.getBoundingClientRect();
|
|
298
|
+
return [rect.left + rect.width / 2, rect.top + rect.height / 2];
|
|
299
|
+
}
|
|
300
|
+
function targetToPosition(target) {
|
|
301
|
+
if (Array.isArray(target) && target.length === 2 && typeof target[0] === "number" && typeof target[1] === "number") {
|
|
302
|
+
return target;
|
|
303
|
+
} else if (target instanceof HTMLElement) {
|
|
304
|
+
return calculateClickPositionFromElement(target);
|
|
305
|
+
} else if (typeof target === "string") {
|
|
306
|
+
const element = document.querySelector(target);
|
|
307
|
+
if (element) {
|
|
308
|
+
return calculateClickPositionFromElement(element);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return void 0;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
exports.AiCursor = AiCursor;
|
|
315
|
+
//# sourceMappingURL=out.js.map
|
|
316
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ui/ai-cursor/rendering/AiCursorComponent.ts","../../src/ui/ai-cursor/rendering/AiCursorComponent.style.ts","../../src/ui/ai-cursor/rendering/index.ts","../../src/ui/ai-cursor/AiCursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, TemplateResult, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { createTimeline, Timeline } from 'animejs';\nimport { AiCursorComponentStyle } from './AiCursorComponent.style';\n\nexport type Props = {\n /**\n * The event hooks are functions that let you connect the inner logic of the solid js component and the AiCursor Class that acts\n * as an API.\n */\n eventHooks: {\n defineSetPosition: (fn: (position: [number, number]) => void) => void;\n defineAddPositionToQueue: (\n fn: (position: [number, number]) => void\n ) => void;\n definePlayQueue: (fn: () => void) => void;\n defineSetShowCursor: (fn: (show: boolean) => void) => void;\n };\n};\n\n@customElement('ai-cursor')\nexport class AiCursorComponent extends LitElement {\n @property({\n type: Object,\n })\n eventHooks: Props['eventHooks'] = {\n defineSetPosition: () => {},\n defineAddPositionToQueue: () => {},\n definePlayQueue: () => {},\n defineSetShowCursor: () => {},\n };\n\n @property({ type: Boolean })\n isShowingCursor = true;\n @property({ type: String })\n labelText = 'AI Cursor';\n\n @property({ type: Array })\n cursorPosition: [number, number] = [0, 0];\n\n private _timeline: Timeline | undefined;\n\n @state()\n private _cursorRef = createRef<HTMLSpanElement>();\n @state()\n private _labelRef = createRef<HTMLSpanElement>();\n\n constructor() {\n super();\n }\n\n updated(_changedProperties: PropertyValues): void {\n if (_changedProperties.has('_cursorRef')) {\n if (this._cursorRef.value) {\n this.hookUpCallbacks();\n } else {\n this._timeline?.pause();\n this._timeline?.refresh();\n }\n }\n super.updated(_changedProperties);\n }\n\n // Define scoped styles right with your component, in plain CSS\n static styles = AiCursorComponentStyle;\n\n render(): TemplateResult {\n const cursorSvg = html`\n <svg\n width=${24}\n height=${24}\n viewBox=\"0 0 100 100\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clip-path=\"url(#clip0_3576_285)\">\n <path\n class=\"cursor-path\"\n d=\"M2.14849 7.04749C1.35153 4.07321 4.07319 1.35155 7.04747 2.14851L77.3148 20.9766C80.2891 21.7735 81.2853 25.4914 79.108 27.6687L27.6687 79.108C25.4914 81.2853 21.7735 80.2891 20.9766 77.3149L2.14849 7.04749Z\"\n fill=\"currentColor\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_3576_285\">\n <rect width=\"100\" height=\"100\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n `;\n\n return html`\n <span\n id=\"cursor-graphic-parent\"\n ${ref(this._cursorRef)}\n ?hidden=${!this.isShowingCursor}\n >\n ${cursorSvg}\n <span\n ${ref(this._labelRef)}\n id=\"label-text\"\n ?hidden=${!this.isShowingCursor}\n >${this.labelText}</span\n >\n </span>\n `;\n }\n\n // private methods\n\n /**\n * The primary way to control the cursor is using an external API.\n * This interface exposes controlling methods. The Lit Component itself is\n * intended to be a controlled component.\n */\n private hookUpCallbacks(): void {\n const animationTarget = this._cursorRef.value;\n\n if (!animationTarget) {\n return;\n }\n\n this._timeline = createTimeline({ defaults: { duration: 750 } });\n\n if (!this._timeline) {\n return;\n }\n\n this.eventHooks.defineSetPosition((position) => {\n this._timeline?.add(animationTarget, {\n translateX: position[0],\n translateY: position[1],\n duration: 1,\n });\n this._timeline?.play();\n });\n\n this.eventHooks.defineAddPositionToQueue((position) => {\n this._timeline?.add(animationTarget, {\n translateX: position[0],\n translateY: position[1],\n duration: 1000,\n });\n });\n\n this.eventHooks.defineSetShowCursor((show) => {\n this.isShowingCursor = show;\n });\n\n this.eventHooks.definePlayQueue(() => {\n this._timeline?.play();\n });\n }\n\n // Getters\n get cursorRef(): HTMLSpanElement | undefined {\n return this._cursorRef.value;\n }\n\n get labelRef(): HTMLSpanElement | undefined {\n return this._labelRef.value;\n }\n}\n","import { css } from 'lit';\n\nexport const AiCursorComponentStyle = css`\n :host {\n --ai-local-cursor-size: var(--sk-ai-cursor-size, 1rem);\n --ai-local-cursor-label-padding: var(\n --sk-ai-cursor-label-padding,\n 0.25rem 0.25rem\n );\n --ai-local-cursor-border-radius: var(--sk-ai-cursor-border-radius, 0.25rem);\n --ai-local-label-offset: var(--sk-ai-cursor-label-offset, 1rem);\n\n --ai-local-label-font-size: var(--sk-ai-cursor-label-font-size, 12px);\n --ai-local-label-font-weight: var(--sk-ai-cursor-label-font-weight, bold);\n --ai-local-label-color: var(--sk-ai-cursor-label-color, white);\n --ai-local-label-background-color: var(\n --sk-ai-cursor-label-background-color,\n black\n );\n --ai-local-label-border-color: var(\n --sk-ai-cursor-label-border-color,\n white\n );\n --ai-local-label-border-width: var(\n --sk-ai-cursor-label-border-width,\n 0.1rem\n );\n\n color: black;\n stroke: white;\n position: absolute;\n /* Insetting in the parent element (body) */\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n pointer-events: none;\n width: var(--ai-local-cursor-size);\n height: var(--ai-local-cursor-size);\n }\n\n #cursor-graphic-parent {\n position: absolute;\n top: 0;\n left: 0;\n }\n\n #label-text {\n position: absolute;\n color: white;\n font-size: 12px;\n font-weight: bold;\n padding: var(--ai-local-cursor-label-padding);\n border-radius: var(--ai-local-cursor-border-radius);\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n\n width: fit-content;\n min-width: fit-content;\n top: var(--ai-local-label-offset);\n left: var(--ai-local-label-offset);\n\n border: var(--ai-local-label-border-width) solid\n var(--ai-local-label-border-color);\n background-color: var(--ai-local-label-background-color);\n color: var(--ai-local-label-color);\n font-size: var(--ai-local-label-font-size);\n font-weight: var(--ai-local-label-font-weight);\n }\n`;\n","import './AiCursorComponent';\nimport { AiCursorComponent, Props as AiCursorProps } from './AiCursorComponent';\n/**\n * The AI Cursor is a Lit Element.\n * Why Lit.dev?\n * Lit.dev is a tiny on memory and bundle size. It is quite fast in rendering.\n * And since UI elements in this library shall be isolated and scoped components,\n * Lit.dev is a good fit.\n * It follows reactivity principles with very fine granularity,\n *\n * Also Solid.js (which was the first version of that - prooved to be annoying because of jsx compiler extras).\n *\n * A downside of Lit.dev is that it is not a very common library. Further, it is close to the DOM using native DOM APIs.\n * Causing it to be a bit different than libs like react using virtual DOM.\n * For other contributors I would recommend reading the /life-cycle section of the docs.\n *\n * Author: @Pascal-Lohscheidt\n */\nexport const mountAiCursor = (aiCursorProps: AiCursorProps): void => {\n const root = document.body;\n const cursor = document.createElement('ai-cursor') as AiCursorComponent;\n cursor.eventHooks = aiCursorProps.eventHooks;\n\n root.appendChild(cursor);\n};\n","import { mountAiCursor } from './rendering';\nimport { Props as AiCursorProps } from './rendering/AiCursorComponent';\n\ntype Selector = string;\ntype CursorTarget = HTMLElement | Selector | [number, number];\n\n/**\n * The AiCursor is a class that is used to create a cursor element and acts an interface to control the cursor.\n * It is used to move the cursor to a target, show or hide the cursor, and to schedule moves.\n *\n * @example\n * ```ts\n * const cursor = AiCursor.spawn();\n * cursor.moveTo('#target-element');\n * ```\n *\n * @author @Pascal-Lohscheidt\n */\nexport class AiCursor {\n private setPosition?: (position: [number, number]) => void;\n private addPositionToQueue?: (position: [number, number]) => void;\n private playQueue?: () => void;\n private setShowCursor?: (show: boolean) => void;\n\n constructor() {}\n\n // Static constructors\n static spawn(): AiCursor {\n const newCursor = new AiCursor();\n newCursor.mount();\n return newCursor;\n }\n\n jumpTo(target: CursorTarget): void {\n const position = targetToPosition(target);\n if (position) {\n this.setPosition?.(position);\n }\n }\n\n moveTo(target: CursorTarget): void {\n const position = targetToPosition(target);\n if (position) {\n this.addPositionToQueue?.(position);\n this.playQueue?.();\n }\n }\n\n scheduleMoves(targets: CursorTarget[]): void {\n targets.forEach((target) => {\n const position = targetToPosition(target);\n if (position) {\n this.addPositionToQueue?.(position);\n }\n });\n this.playQueue?.();\n }\n\n show(): void {\n this.setShowCursor?.(true);\n }\n\n hide(): void {\n this.setShowCursor?.(false);\n }\n\n private mount(): void {\n mountAiCursor({\n eventHooks: {\n defineSetPosition: (callback): void => {\n this.setPosition = callback;\n },\n defineAddPositionToQueue: (callback): void => {\n this.addPositionToQueue = callback;\n },\n definePlayQueue: (callback): void => {\n this.playQueue = callback;\n },\n defineSetShowCursor: (callback): void => {\n this.setShowCursor = callback;\n },\n },\n } satisfies AiCursorProps);\n }\n}\n\nfunction calculateClickPositionFromElement(element: Element): [number, number] {\n const rect = element.getBoundingClientRect();\n return [rect.left + rect.width / 2, rect.top + rect.height / 2];\n}\n\nfunction targetToPosition(target: CursorTarget): [number, number] | undefined {\n if (\n Array.isArray(target) &&\n target.length === 2 &&\n typeof target[0] === 'number' &&\n typeof target[1] === 'number'\n ) {\n return target;\n } else if (target instanceof HTMLElement) {\n return calculateClickPositionFromElement(target);\n } else if (typeof target === 'string') {\n const element = document.querySelector(target);\n if (element) {\n return calculateClickPositionFromElement(element);\n }\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type Selector = string;
|
|
2
|
+
type CursorTarget = HTMLElement | Selector | [number, number];
|
|
3
|
+
/**
|
|
4
|
+
* The AiCursor is a class that is used to create a cursor element and acts an interface to control the cursor.
|
|
5
|
+
* It is used to move the cursor to a target, show or hide the cursor, and to schedule moves.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const cursor = AiCursor.spawn();
|
|
10
|
+
* cursor.moveTo('#target-element');
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @author @Pascal-Lohscheidt
|
|
14
|
+
*/
|
|
15
|
+
declare class AiCursor {
|
|
16
|
+
private setPosition?;
|
|
17
|
+
private addPositionToQueue?;
|
|
18
|
+
private playQueue?;
|
|
19
|
+
private setShowCursor?;
|
|
20
|
+
constructor();
|
|
21
|
+
static spawn(): AiCursor;
|
|
22
|
+
jumpTo(target: CursorTarget): void;
|
|
23
|
+
moveTo(target: CursorTarget): void;
|
|
24
|
+
scheduleMoves(targets: CursorTarget[]): void;
|
|
25
|
+
show(): void;
|
|
26
|
+
hide(): void;
|
|
27
|
+
private mount;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { AiCursor };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type Selector = string;
|
|
2
|
+
type CursorTarget = HTMLElement | Selector | [number, number];
|
|
3
|
+
/**
|
|
4
|
+
* The AiCursor is a class that is used to create a cursor element and acts an interface to control the cursor.
|
|
5
|
+
* It is used to move the cursor to a target, show or hide the cursor, and to schedule moves.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const cursor = AiCursor.spawn();
|
|
10
|
+
* cursor.moveTo('#target-element');
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @author @Pascal-Lohscheidt
|
|
14
|
+
*/
|
|
15
|
+
declare class AiCursor {
|
|
16
|
+
private setPosition?;
|
|
17
|
+
private addPositionToQueue?;
|
|
18
|
+
private playQueue?;
|
|
19
|
+
private setShowCursor?;
|
|
20
|
+
constructor();
|
|
21
|
+
static spawn(): AiCursor;
|
|
22
|
+
jumpTo(target: CursorTarget): void;
|
|
23
|
+
moveTo(target: CursorTarget): void;
|
|
24
|
+
scheduleMoves(targets: CursorTarget[]): void;
|
|
25
|
+
show(): void;
|
|
26
|
+
hide(): void;
|
|
27
|
+
private mount;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { AiCursor };
|