@tstdl/base 0.92.15 → 0.92.17

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.
@@ -1,18 +1,11 @@
1
- import type { SchemaTestable } from '../schema/index.js';
2
- import type { Enumeration, OneOrMany, TypedOmit } from '../types.js';
3
- import type { AiService, AnalyzeContentResult, ClassificationResult, SpecializedGenerationResult } from './ai.service.js';
4
- import type { Content, ContentPart, GenerationOptions, GenerationRequest, GenerationResult, SchemaFunctionDeclarations, SchemaFunctionDeclarationsResult } from './types.js';
1
+ import type { OneOrMany } from '../types.js';
2
+ import type { AiService, CallFunctionsOptions, SpecializedGenerationResult } from './ai.service.js';
3
+ import type { Content, GenerationRequest, GenerationResult, SchemaFunctionDeclarations, SchemaFunctionDeclarationsResult } from './types.js';
5
4
  export declare class AiSession {
6
5
  #private;
7
6
  readonly contents: Content[];
8
7
  constructor(aiService: AiService);
9
8
  addContent(content: OneOrMany<Content>): void;
10
- analyzeContent<T extends Enumeration>(parts: OneOrMany<ContentPart>, types: T, options?: GenerationOptions & {
11
- targetLanguage?: string;
12
- maximumNumberOfTags?: number;
13
- }): Promise<SpecializedGenerationResult<AnalyzeContentResult<T>>>;
14
- classify<T extends Enumeration>(parts: OneOrMany<ContentPart>, types: T, options?: GenerationOptions & Pick<GenerationRequest, 'model'>): Promise<SpecializedGenerationResult<ClassificationResult<T>>>;
15
- extractData<T>(parts: OneOrMany<ContentPart>, schema: SchemaTestable<T>, options?: GenerationOptions & Pick<GenerationRequest, 'model'>): Promise<SpecializedGenerationResult<T>>;
16
- callFunctions<const T extends SchemaFunctionDeclarations>(functions: T, content: Content | [Content, ...Content[]], options?: Pick<GenerationRequest, 'model' | 'systemInstruction'> & GenerationOptions): Promise<SpecializedGenerationResult<SchemaFunctionDeclarationsResult<T>[]>>;
17
- generate(content: Content | [Content, ...Content[]], request?: TypedOmit<GenerationRequest, 'contents'>): Promise<GenerationResult>;
9
+ callFunctions<const T extends SchemaFunctionDeclarations>(options: CallFunctionsOptions<T>): Promise<SpecializedGenerationResult<SchemaFunctionDeclarationsResult<T>[]>>;
10
+ generate(request: GenerationRequest): Promise<GenerationResult>;
18
11
  }
package/ai/ai-session.js CHANGED
@@ -8,35 +8,14 @@ export class AiSession {
8
8
  addContent(content) {
9
9
  this.contents.push(...toArray(content));
10
10
  }
11
- async analyzeContent(parts, types, options) {
12
- const newContents = this.#aiService.getAnalyzeContentConents(parts);
13
- this.contents.push(...newContents);
14
- const result = await this.#aiService.analyzeContent(parts, types, options);
11
+ async callFunctions(options) {
12
+ this.contents.push(...toArray(options.contents));
13
+ const result = await this.#aiService.callFunctions({ ...options, contents: this.contents });
15
14
  this.contents.push(result.raw.content);
16
15
  return result;
17
16
  }
18
- async classify(parts, types, options) {
19
- const newContents = this.#aiService.getExtractDataConents(parts);
20
- this.contents.push(...newContents);
21
- const result = await this.#aiService.classify(parts, types, options);
22
- this.contents.push(result.raw.content);
23
- return result;
24
- }
25
- async extractData(parts, schema, options) {
26
- const newContents = this.#aiService.getExtractDataConents(parts);
27
- this.contents.push(...newContents);
28
- const result = await this.#aiService.extractData(parts, schema, options);
29
- this.contents.push(result.raw.content);
30
- return result;
31
- }
32
- async callFunctions(functions, content, options) {
33
- this.contents.push(...toArray(content));
34
- const result = await this.#aiService.callFunctions(functions, this.contents, options);
35
- this.contents.push(result.raw.content);
36
- return result;
37
- }
38
- async generate(content, request) {
39
- this.contents.push(...toArray(content));
17
+ async generate(request) {
18
+ this.contents.push(...toArray(request.contents));
40
19
  const result = await this.#aiService.generate({ ...request, contents: this.contents });
41
20
  this.contents.push(result.content);
42
21
  return result;
@@ -1,4 +1,3 @@
1
- import '../polyfills.js';
2
1
  import { Resolvable, type resolveArgumentType } from '../injector/interfaces.js';
3
2
  import { OneOrMany, SchemaTestable } from '../schema/index.js';
4
3
  import { Enumeration as EnumerationType, EnumerationValue } from '../types.js';
@@ -24,6 +23,9 @@ export type AnalyzeContentResult<T extends EnumerationType> = {
24
23
  documentTypes: ClassificationResult<T>[];
25
24
  tags: string[];
26
25
  };
26
+ export type CallFunctionsOptions<T extends SchemaFunctionDeclarations> = Pick<GenerationRequest, 'contents' | 'model' | 'systemInstruction'> & GenerationOptions & {
27
+ functions: T;
28
+ };
27
29
  export declare class AiService implements Resolvable<AiServiceArgument> {
28
30
  #private;
29
31
  readonly defaultModel: AiModel;
@@ -40,7 +42,7 @@ export declare class AiService implements Resolvable<AiServiceArgument> {
40
42
  maximumNumberOfTags?: number;
41
43
  }): Promise<SpecializedGenerationResult<AnalyzeContentResult<T>>>;
42
44
  getAnalyzeContentConents(parts: OneOrMany<ContentPart>): Content[];
43
- callFunctions<const T extends SchemaFunctionDeclarations>(functions: T, contents: Content[], options?: Pick<GenerationRequest, 'model' | 'systemInstruction'> & GenerationOptions): Promise<SpecializedGenerationResult<SchemaFunctionDeclarationsResult<T>[]>>;
45
+ callFunctions<const T extends SchemaFunctionDeclarations>(options: CallFunctionsOptions<T>): Promise<SpecializedGenerationResult<SchemaFunctionDeclarationsResult<T>[]>>;
44
46
  generate(request: GenerationRequest): Promise<GenerationResult>;
45
47
  private convertContents;
46
48
  private convertContent;
package/ai/ai.service.js CHANGED
@@ -4,8 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import '../polyfills.js';
8
- import { FunctionCallingMode as GoogleFunctionCallingMode, GoogleGenerativeAI } from '@google/generative-ai';
7
+ import { FinishReason, FunctionCallingMode as GoogleFunctionCallingMode, GoogleGenerativeAI } from '@google/generative-ai';
9
8
  import { NotSupportedError } from '../errors/not-supported.error.js';
10
9
  import { Singleton } from '../injector/decorators.js';
11
10
  import { inject, injectArgument } from '../injector/inject.js';
@@ -136,22 +135,21 @@ Always output the content and tags in ${options?.targetLanguage ?? 'the same lan
136
135
  ]
137
136
  }];
138
137
  }
139
- async callFunctions(functions, contents, options) {
138
+ async callFunctions(options) {
140
139
  const generation = await this.generate({
141
- model: options?.model,
140
+ model: options.model,
142
141
  generationOptions: {
143
- maxOutputTokens: 4096,
144
142
  temperature: 0.5,
145
143
  ...options
146
144
  },
147
- systemInstruction: options?.systemInstruction,
148
- functions,
145
+ systemInstruction: options.systemInstruction,
146
+ functions: options.functions,
149
147
  functionCallingMode: 'force',
150
- contents
148
+ contents: options.contents
151
149
  });
152
150
  const result = [];
153
151
  for (const call of generation.functionCalls) {
154
- const fn = assertDefinedPass(functions[call.name], 'Function in response not declared.');
152
+ const fn = assertDefinedPass(options.functions[call.name], 'Function in response not declared.');
155
153
  const parameters = fn.parameters.parse(call.parameters);
156
154
  const handlerResult = isSchemaFunctionDeclarationWithHandler(fn) ? await fn.handler(parameters) : undefined;
157
155
  result.push({ functionName: call.name, parameters: parameters, handlerResult: handlerResult });
@@ -162,7 +160,6 @@ Always output the content and tags in ${options?.targetLanguage ?? 'the same lan
162
160
  };
163
161
  }
164
162
  async generate(request) {
165
- const googleContent = this.convertContents(request.contents);
166
163
  const googleFunctionDeclarations = isDefined(request.functions) ? this.convertFunctions(request.functions) : undefined;
167
164
  const generationConfig = {
168
165
  maxOutputTokens: request.generationOptions?.maxOutputTokens,
@@ -174,31 +171,61 @@ Always output the content and tags in ${options?.targetLanguage ?? 'the same lan
174
171
  presencePenalty: request.generationOptions?.presencePenalty,
175
172
  frequencyPenalty: request.generationOptions?.frequencyPenalty
176
173
  };
177
- const generation = await this.getModel(request.model ?? this.defaultModel).generateContent({
178
- generationConfig,
179
- systemInstruction: request.systemInstruction,
180
- tools: isDefined(googleFunctionDeclarations) ? [{ functionDeclarations: googleFunctionDeclarations }] : undefined,
181
- toolConfig: isDefined(request.functionCallingMode)
182
- ? { functionCallingConfig: { mode: functionCallingModeMap[request.functionCallingMode] } }
183
- : undefined,
184
- contents: googleContent
185
- });
186
- const content = this.convertGoogleContent(generation.response.candidates.at(0).content);
174
+ const googleContent = this.convertContents(request.contents);
175
+ const generationContent = { role: 'model', parts: [] };
176
+ const maxTotalOutputTokens = request.generationOptions?.maxOutputTokens ?? 8192;
177
+ let iterations = 0;
178
+ let totalPromptTokens = 0;
179
+ let totalOutputTokens = 0;
180
+ let candidate;
181
+ while (totalOutputTokens < maxTotalOutputTokens) {
182
+ const generation = await this.getModel(request.model ?? this.defaultModel).generateContent({
183
+ generationConfig: {
184
+ ...generationConfig,
185
+ maxOutputTokens: Math.min(8192, maxTotalOutputTokens - totalOutputTokens)
186
+ },
187
+ systemInstruction: request.systemInstruction,
188
+ tools: isDefined(googleFunctionDeclarations) ? [{ functionDeclarations: googleFunctionDeclarations }] : undefined,
189
+ toolConfig: isDefined(request.functionCallingMode)
190
+ ? { functionCallingConfig: { mode: functionCallingModeMap[request.functionCallingMode] } }
191
+ : undefined,
192
+ contents: googleContent
193
+ });
194
+ iterations++;
195
+ candidate = generation.response.candidates.at(0);
196
+ // On first generation only
197
+ if (generationContent.parts.length == 0) {
198
+ googleContent.push(generationContent);
199
+ }
200
+ generationContent.parts.push(...candidate.content.parts);
201
+ totalPromptTokens += generation.response.usageMetadata.promptTokenCount;
202
+ totalOutputTokens += generation.response.usageMetadata.candidatesTokenCount;
203
+ if (candidate.finishReason != FinishReason.MAX_TOKENS) {
204
+ break;
205
+ }
206
+ }
207
+ const content = this.convertGoogleContent(generationContent);
187
208
  const textParts = content.parts.filter((part) => hasOwnProperty(part, 'text')).map((part) => part.text);
188
209
  const functionCallParts = content.parts.filter((part) => hasOwnProperty(part, 'functionCall')).map((part) => part.functionCall);
189
210
  return {
190
211
  content,
191
212
  text: textParts.length > 0 ? textParts.join('') : null,
192
213
  functionCalls: functionCallParts,
214
+ finishReason: candidate.finishReason == FinishReason.MAX_TOKENS
215
+ ? 'maxTokens'
216
+ : candidate.finishReason == FinishReason.STOP
217
+ ? 'stop'
218
+ : 'unknown',
193
219
  usage: {
194
- prompt: generation.response.usageMetadata.promptTokenCount,
195
- output: generation.response.usageMetadata.candidatesTokenCount,
196
- total: generation.response.usageMetadata.totalTokenCount
220
+ iterations,
221
+ prompt: totalPromptTokens,
222
+ output: totalOutputTokens,
223
+ total: totalPromptTokens + totalOutputTokens
197
224
  }
198
225
  };
199
226
  }
200
227
  convertContents(contents) {
201
- return contents.map((content) => this.convertContent(content));
228
+ return toArray(contents).map((content) => this.convertContent(content));
202
229
  }
203
230
  convertContent(content) {
204
231
  return {
package/ai/types.d.ts CHANGED
@@ -49,6 +49,7 @@ export type Content = {
49
49
  parts: readonly ContentPart[];
50
50
  };
51
51
  export type FunctionCallingMode = 'auto' | 'force' | 'none';
52
+ export type FinishReason = 'stop' | 'maxTokens' | 'unknown';
52
53
  export type AiModel = LiteralUnion<'gemini-2.0-flash-exp' | 'gemini-exp-1206' | 'gemini-2.0-flash-thinking-exp-1219', string>;
53
54
  export type GenerationOptions = {
54
55
  maxOutputTokens?: number;
@@ -61,13 +62,14 @@ export type GenerationOptions = {
61
62
  export type GenerationRequest = {
62
63
  model?: AiModel;
63
64
  systemInstruction?: string;
64
- contents: readonly Content[];
65
+ contents: Content | readonly Content[];
65
66
  functions?: SchemaFunctionDeclarations;
66
67
  functionCallingMode?: FunctionCallingMode;
67
68
  generationSchema?: SchemaTestable;
68
69
  generationOptions?: GenerationOptions;
69
70
  };
70
71
  export type GenerationUsage = {
72
+ iterations: number;
71
73
  prompt: number;
72
74
  output: number;
73
75
  total: number;
@@ -76,6 +78,7 @@ export type GenerationResult = {
76
78
  content: Content;
77
79
  text: string | null;
78
80
  functionCalls: FunctionCall[];
81
+ finishReason: FinishReason;
79
82
  usage: GenerationUsage;
80
83
  };
81
84
  export declare function declareFunctions<T extends SchemaFunctionDeclarations>(declarations: T): T;
@@ -1,8 +1,7 @@
1
- import type { AfterResolve } from '../../injector/index.js';
2
- import { afterResolve } from '../../injector/index.js';
3
- import type { Record } from '../../types.js';
1
+ import { type AfterResolve, afterResolve } from '../../injector/index.js';
2
+ import type { BinaryData, Record } from '../../types.js';
4
3
  import type { RefreshToken, SecretCheckResult, SecretResetToken, Token } from '../models/index.js';
5
- import type { SecretTestResult } from './authentication-secret-requirements.validator.js';
4
+ import { type SecretTestResult } from './authentication-secret-requirements.validator.js';
6
5
  export type CreateTokenData<AdditionalTokenPayload extends Record> = {
7
6
  tokenVersion?: number;
8
7
  jwtId?: string;
@@ -1,5 +1,5 @@
1
1
  import type { HttpServerRequest } from '../../http/server/index.js';
2
- import type { Record } from '../../types.js';
2
+ import type { BinaryData, Record } from '../../types.js';
3
3
  import type { RefreshToken, SecretResetToken, Token } from '../models/index.js';
4
4
  /**
5
5
  *
package/file/mime-type.js CHANGED
@@ -1,7 +1,5 @@
1
- import { dynamicImport } from '../import.js';
2
- import { decodeTextStream } from '../utils/encoding.js';
3
- import { readTextStream } from '../utils/stream/stream-reader.js';
4
- import { isReadableStream, isString, isUint8Array } from '../utils/type-guards.js';
1
+ import { spawnCommand } from '../process/spawn.js';
2
+ import { isDefined, isString } from '../utils/type-guards.js';
5
3
  import { mimeTypesMap } from './mime-types.js';
6
4
  export async function getMimeType(file) {
7
5
  const path = isString(file) ? file : '-';
@@ -12,22 +10,10 @@ export function getMimeTypeExtensions(mimeType) {
12
10
  return mimeTypesMap.get(mimeType) ?? [];
13
11
  }
14
12
  async function spawnFileCommand(args, file) {
15
- const { spawn } = await dynamicImport('node:child_process');
16
- const { Readable, Writable } = await dynamicImport('node:stream');
17
- const process = spawn('file', args, { stdio: 'pipe' });
18
- const stdin = Writable.toWeb(process.stdin);
19
- const stdout = Readable.toWeb(process.stdout).pipeThrough(decodeTextStream());
20
- if (isReadableStream(file)) {
21
- await file.pipeTo(stdin);
22
- }
23
- else if (isUint8Array(file)) {
24
- const writer = stdin.getWriter();
25
- try {
26
- await writer.write(file);
27
- await writer.close();
28
- }
29
- catch { /* File command closes stream as soon as it has the required data */ }
30
- }
31
- const output = await readTextStream(stdout);
32
- return output.trim();
13
+ const process = await spawnCommand('file', args, { stdinPipeOptions: { preventCancel: true } });
14
+ const [stdout] = await Promise.all([
15
+ process.readOutput(),
16
+ isDefined(file) ? process.write(file) : undefined
17
+ ]);
18
+ return stdout.trim();
33
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.92.15",
3
+ "version": "0.92.17",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -144,7 +144,7 @@
144
144
  "tsx": "^4.19.2",
145
145
  "typedoc": "0.27",
146
146
  "typedoc-plugin-missing-exports": "3.1",
147
- "typescript": "5.6"
147
+ "typescript": "5.7"
148
148
  },
149
149
  "peerDependencies": {
150
150
  "@elastic/elasticsearch": "^8.17",
package/pdf/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './pdf.service.js';
2
+ export * from './utils.js';
package/pdf/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from './pdf.service.js';
2
+ export * from './utils.js';
package/pdf/utils.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function getPdfPageCount(file: string): Promise<number>;
package/pdf/utils.js ADDED
@@ -0,0 +1,11 @@
1
+ import { spawnCommand } from '../process/spawn.js';
2
+ export async function getPdfPageCount(file) {
3
+ const process = await spawnCommand('qpdf', ['--show-npages', file]);
4
+ const { code } = await process.wait();
5
+ if (code != 0) {
6
+ const errorOutput = await process.readError();
7
+ throw new Error(errorOutput.trim());
8
+ }
9
+ const output = await process.readOutput();
10
+ return Number(output);
11
+ }
@@ -5,11 +5,13 @@ export type SpawnCommandResult = TransformStream<Uint8Array, Uint8Array> & {
5
5
  write(chunk: ReadableStream<Uint8Array> | Uint8Array | string): Promise<void>;
6
6
  readOutputBytes(): Promise<Uint8Array>;
7
7
  readOutput(): Promise<string>;
8
- readErrBytes(): Promise<Uint8Array>;
9
- readErr(): Promise<string>;
8
+ readErrorBytes(): Promise<Uint8Array>;
9
+ readError(): Promise<string>;
10
10
  wait(): Promise<{
11
11
  code: number | null;
12
12
  signal: string | null;
13
13
  }>;
14
14
  };
15
- export declare function spawnCommand(command: string, args: string[]): Promise<SpawnCommandResult>;
15
+ export declare function spawnCommand(command: string, args?: string[], options?: {
16
+ stdinPipeOptions?: StreamPipeOptions;
17
+ }): Promise<SpawnCommandResult>;
package/process/spawn.js CHANGED
@@ -3,7 +3,7 @@ import { decodeTextStream, encodeUtf8Stream } from '../utils/encoding.js';
3
3
  import { readBinaryStream, readTextStream } from '../utils/stream/stream-reader.js';
4
4
  import { toReadableStream } from '../utils/stream/to-readable-stream.js';
5
5
  import { isReadableStream, isString, isUint8Array } from '../utils/type-guards.js';
6
- export async function spawnCommand(command, args) {
6
+ export async function spawnCommand(command, args, options) {
7
7
  const { spawn } = await dynamicImport('node:child_process');
8
8
  const { Readable, Writable } = await dynamicImport('node:stream');
9
9
  const process = spawn(command, args, { stdio: 'pipe' });
@@ -16,13 +16,13 @@ export async function spawnCommand(command, args) {
16
16
  const stderr = Readable.toWeb(process.stderr);
17
17
  async function write(data) {
18
18
  if (isReadableStream(data)) {
19
- await data.pipeTo(writable);
19
+ await data.pipeTo(writable, options?.stdinPipeOptions);
20
20
  }
21
21
  else if (isUint8Array(data)) {
22
- await toReadableStream(data).pipeTo(writable);
22
+ await toReadableStream(data).pipeTo(writable, options?.stdinPipeOptions);
23
23
  }
24
24
  else if (isString(data)) {
25
- await toReadableStream(data).pipeThrough(encodeUtf8Stream()).pipeTo(writable);
25
+ await toReadableStream(data).pipeThrough(encodeUtf8Stream()).pipeTo(writable, options?.stdinPipeOptions);
26
26
  }
27
27
  }
28
28
  async function readOutputBytes() {
@@ -46,10 +46,10 @@ export async function spawnCommand(command, args) {
46
46
  write,
47
47
  readOutputBytes,
48
48
  readOutput,
49
- readErrBytes,
50
- readErr,
49
+ readErrorBytes: readErrBytes,
50
+ readError: readErr,
51
51
  async wait() {
52
52
  return signalPromise;
53
- },
53
+ }
54
54
  };
55
55
  }
package/rpc/rpc.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { SerializationOptions } from '../serializer/index.js';
1
+ import { type SerializationOptions } from '../serializer/index.js';
2
2
  import type { RpcRemote, RpcRemoteInput } from './model.js';
3
3
  import type { RpcAdapter } from './rpc.adapter.js';
4
4
  import type { RpcEndpoint } from './rpc.endpoint.js';
package/rpc/rpc.js CHANGED
@@ -137,7 +137,8 @@ function createProxy(channel, path = []) {
137
137
  handlers[method] = deferThrow(() => new NotSupportedError(`${method} not supported on rpc proxies.`));
138
138
  }
139
139
  }
140
- return new Proxy(RpcProxy, handlers);
140
+ proxy = new Proxy(RpcProxy, handlers);
141
+ return proxy;
141
142
  }
142
143
  function exposeObject(object, channel) {
143
144
  const { endpoint } = channel;
@@ -4,7 +4,7 @@ interface TypedArrayConstructor {
4
4
  new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): TypedArray;
5
5
  }
6
6
  export declare function serializeArrayBuffer(buffer: ArrayBuffer): string;
7
- export declare function deserializeArrayBuffer(data: string): ArrayBuffer;
7
+ export declare function deserializeArrayBuffer(data: string): ArrayBufferLike;
8
8
  export declare function serializeTypedArray(array: TypedArray): string;
9
9
  export declare function getTypedArrayDeserializer(constructor: TypedArrayConstructor): (data: string) => TypedArray;
10
10
  export declare function serializeBuffer(buffer: Buffer): string;
@@ -1,4 +1,4 @@
1
- import { Subject, concatAll, exhaustAll, isObservable, mergeAll, of, switchAll, takeUntil } from 'rxjs';
1
+ import { Subject, concatAll, exhaustAll, from, isObservable, mergeAll, of, switchAll, takeUntil } from 'rxjs';
2
2
  import { registerFinalization } from '../../memory/finalization.js';
3
3
  import { isPromise } from '../../utils/type-guards.js';
4
4
  import { computed, effect, toSignal, untracked } from '../api.js';
@@ -9,15 +9,23 @@ const operatorMap = {
9
9
  switch: switchAll,
10
10
  };
11
11
  export function deriveAsync(source, options) {
12
- const outerSource = computed(source);
12
+ const outerSource = computed(() => {
13
+ const rawSource = source();
14
+ if (isPromise(rawSource)) {
15
+ return from(rawSource);
16
+ }
17
+ if (isObservable(rawSource)) {
18
+ return rawSource;
19
+ }
20
+ return of(rawSource);
21
+ });
13
22
  const source$ = new Subject();
14
23
  const destroy$ = new Subject();
15
24
  const operator = operatorMap[options?.behavior ?? 'switch'];
16
25
  const valueSource$ = source$.pipe(operator(), takeUntil(destroy$));
17
26
  const result = toSignal(valueSource$, options);
18
27
  const effectRef = effect(() => {
19
- const rawSource = outerSource();
20
- const observableInput = (isPromise(rawSource) || isObservable(rawSource)) ? rawSource : of(rawSource);
28
+ const observableInput = outerSource();
21
29
  untracked(() => source$.next(observableInput));
22
30
  });
23
31
  registerFinalization(result, () => {
package/utils/binary.d.ts CHANGED
@@ -4,14 +4,13 @@ import type { BinaryData, Type } from '../types.js';
4
4
  * @param data data to get ArrayBuffer from
5
5
  * @param clone force cloning (might still clone if datas underlying buffer is larger than its view)
6
6
  */
7
- export declare function toArrayBuffer(data: BinaryData, clone?: boolean): ArrayBuffer;
7
+ export declare function toArrayBuffer(data: BinaryData, clone?: boolean): ArrayBufferLike;
8
8
  /**
9
- * eslint-disable-next-line @typescript-eslint/no-shadow
10
- * convert to Uint8Array
9
+ * Convert to Uint8Array
11
10
  * @param data binary data
12
11
  * @param clone whether to clone buffer or not
13
12
  */
14
13
  export declare function toUint8Array(data: BinaryData, clone?: boolean): Uint8Array;
15
- export declare function concatArrayBuffers(buffers: ArrayBufferLike[]): ArrayBuffer;
14
+ export declare function concatArrayBuffers(buffers: ArrayBufferLike[]): ArrayBufferLike;
16
15
  export declare function concatArrayBufferViews<T extends ArrayBufferView>(arrays: T[], totalLength?: number): T;
17
16
  export declare function concatArrayBufferViews<T extends ArrayBufferView>(arrays: ArrayBufferView[], targetType: Type<T, [ArrayBufferLike, number, number]>, totalLength?: number): T;
package/utils/binary.js CHANGED
@@ -16,8 +16,7 @@ export function toArrayBuffer(data, clone = false) {
16
16
  return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
17
17
  }
18
18
  /**
19
- * eslint-disable-next-line @typescript-eslint/no-shadow
20
- * convert to Uint8Array
19
+ * Convert to Uint8Array
21
20
  * @param data binary data
22
21
  * @param clone whether to clone buffer or not
23
22
  */
@@ -1,4 +1,4 @@
1
- import type { AbstractConstructor, JsonPrimitive, PascalCase, Primitive, TypedArray } from '../types.js';
1
+ import type { AbstractConstructor, BinaryData, JsonPrimitive, PascalCase, Primitive, TypedArray } from '../types.js';
2
2
  export type AssertionMessage = string | (() => string);
3
3
  export type IsFunction<T> = <U extends T = T>(value: any) => value is U;
4
4
  export type IsNotFunction<T> = <V>(value: V) => value is Exclude<V, T>;
@@ -6,19 +6,7 @@ export type AssertFunction<T> = <U extends T = T>(value: any, message?: Assertio
6
6
  export type AssertNotFunction<T> = <V>(value: V, message?: AssertionMessage) => asserts value is Exclude<V, T>;
7
7
  export type AssertPassFunction<T> = <U extends T = T>(value: any, message?: AssertionMessage) => U;
8
8
  export type AssertNotPassFunction<T> = <V>(value: V, message?: AssertionMessage) => Exclude<V, T>;
9
- export type GuardFunctions<N extends string, T> = {
10
- [P in `is${PascalCase<N>}`]: IsFunction<T>;
11
- } & {
12
- [P in `isNot${PascalCase<N>}`]: IsNotFunction<T>;
13
- } & {
14
- [P in `assert${PascalCase<N>}`]: AssertFunction<T>;
15
- } & {
16
- [P in `assertNot${PascalCase<N>}`]: AssertNotFunction<T>;
17
- } & {
18
- [P in `assert${PascalCase<N>}Pass`]: AssertPassFunction<T>;
19
- } & {
20
- [P in `assertNot${PascalCase<N>}Pass`]: AssertNotPassFunction<T>;
21
- };
9
+ export type GuardFunctions<N extends string, T> = Record<`is${PascalCase<N>}`, IsFunction<T>> & Record<`isNot${PascalCase<N>}`, IsNotFunction<T>> & Record<`assert${PascalCase<N>}`, AssertFunction<T>> & Record<`assertNot${PascalCase<N>}`, AssertNotFunction<T>> & Record<`assert${PascalCase<N>}Pass`, AssertPassFunction<T>> & Record<`assertNot${PascalCase<N>}Pass`, AssertNotPassFunction<T>>;
22
10
  export declare function assert(condition: boolean, message?: AssertionMessage): asserts condition;
23
11
  export declare function assertNot(condition: boolean, message?: AssertionMessage): asserts condition;
24
12
  export declare function createGuards<N extends string, T>(name: N, testFn: (value: any) => value is T): GuardFunctions<N, T>;