@mikesaintsg/core 0.0.3 → 0.0.4
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/dist/index.d.ts +170 -2
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -140,7 +140,7 @@ export declare function createFormDirtyGuard<TFormData = unknown, TPage extends
|
|
|
140
140
|
* registry.register({ ...schema, execute: handler })
|
|
141
141
|
* ```
|
|
142
142
|
*/
|
|
143
|
-
export declare function createRetrievalTool<TMetadata = unknown>(options: RetrievalToolOptions<TMetadata>):
|
|
143
|
+
export declare function createRetrievalTool<TMetadata = unknown>(options: RetrievalToolOptions<TMetadata>): RetrievalToolInterface;
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
* Create a session persistence adapter for storing inference sessions.
|
|
@@ -326,6 +326,9 @@ export declare type ErrorCode<T extends {
|
|
|
326
326
|
readonly code: string;
|
|
327
327
|
}> = T['code'];
|
|
328
328
|
|
|
329
|
+
/** Generation finish reason */
|
|
330
|
+
export declare type FinishReason = 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'error';
|
|
331
|
+
|
|
329
332
|
/** Default form dirty guard message */
|
|
330
333
|
export declare const FORM_DIRTY_DEFAULT_MESSAGE = "You have unsaved changes. Are you sure you want to leave?";
|
|
331
334
|
|
|
@@ -381,6 +384,38 @@ export declare interface FrameSummary {
|
|
|
381
384
|
/** Frame type discriminator */
|
|
382
385
|
export declare type FrameType = 'system' | 'instruction' | 'section' | 'file' | 'document' | 'example' | 'tool' | 'memory' | 'retrieval' | 'custom';
|
|
383
386
|
|
|
387
|
+
/** Generation defaults for provider adapters */
|
|
388
|
+
export declare interface GenerationDefaults {
|
|
389
|
+
readonly model?: string;
|
|
390
|
+
readonly temperature?: number;
|
|
391
|
+
readonly maxTokens?: number;
|
|
392
|
+
readonly topP?: number;
|
|
393
|
+
readonly stop?: readonly string[];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Generation options */
|
|
397
|
+
export declare interface GenerationOptions extends AbortableOptions {
|
|
398
|
+
readonly model?: string;
|
|
399
|
+
readonly temperature?: number;
|
|
400
|
+
readonly maxTokens?: number;
|
|
401
|
+
readonly topP?: number;
|
|
402
|
+
readonly tools?: readonly ToolSchema[];
|
|
403
|
+
readonly toolChoice?: 'auto' | 'none' | 'required' | {
|
|
404
|
+
readonly name: string;
|
|
405
|
+
};
|
|
406
|
+
readonly stop?: readonly string[];
|
|
407
|
+
readonly timeout?: TimeoutOptions;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/** Generation result */
|
|
411
|
+
export declare interface GenerationResult {
|
|
412
|
+
readonly text: string;
|
|
413
|
+
readonly toolCalls: readonly ToolCall[];
|
|
414
|
+
readonly finishReason: FinishReason;
|
|
415
|
+
readonly usage?: UsageStats;
|
|
416
|
+
readonly aborted: boolean;
|
|
417
|
+
}
|
|
418
|
+
|
|
384
419
|
/**
|
|
385
420
|
* Type guard for ecosystem errors.
|
|
386
421
|
*
|
|
@@ -498,6 +533,28 @@ export declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U):
|
|
|
498
533
|
*/
|
|
499
534
|
export declare function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
500
535
|
|
|
536
|
+
/** Message object */
|
|
537
|
+
export declare interface Message {
|
|
538
|
+
readonly id: string;
|
|
539
|
+
readonly role: MessageRole;
|
|
540
|
+
readonly content: MessageContent;
|
|
541
|
+
readonly createdAt: number;
|
|
542
|
+
readonly metadata?: MessageMetadata;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/** Message content types */
|
|
546
|
+
export declare type MessageContent = string | ToolCallContent | ToolResultContent;
|
|
547
|
+
|
|
548
|
+
/** Message metadata */
|
|
549
|
+
export declare interface MessageMetadata {
|
|
550
|
+
readonly model?: string;
|
|
551
|
+
readonly tokenCount?: number;
|
|
552
|
+
readonly finishReason?: FinishReason;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/** Message role */
|
|
556
|
+
export declare type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
557
|
+
|
|
501
558
|
/**
|
|
502
559
|
* Minimal database access interface for cross-package adapters.
|
|
503
560
|
* Used by persistence adapters to access IndexedDB without
|
|
@@ -598,6 +655,36 @@ export declare interface PriorityAdapterInterface {
|
|
|
598
655
|
compare(a: ContextFrame, b: ContextFrame): number;
|
|
599
656
|
}
|
|
600
657
|
|
|
658
|
+
/**
|
|
659
|
+
* Provider adapter interface - LLM provider integration.
|
|
660
|
+
* Implemented for each supported provider (OpenAI, Anthropic, etc.).
|
|
661
|
+
*/
|
|
662
|
+
export declare interface ProviderAdapterInterface {
|
|
663
|
+
/** Get adapter identifier */
|
|
664
|
+
getId(): string;
|
|
665
|
+
/**
|
|
666
|
+
* Generate completion.
|
|
667
|
+
* @param messages - Messages to send
|
|
668
|
+
* @param options - Generation options
|
|
669
|
+
*/
|
|
670
|
+
generate(messages: readonly Message[], options: GenerationOptions): StreamHandleInterface;
|
|
671
|
+
/** Check if provider supports tools */
|
|
672
|
+
supportsTools(): boolean;
|
|
673
|
+
/** Check if provider supports streaming */
|
|
674
|
+
supportsStreaming(): boolean;
|
|
675
|
+
/** Get all capabilities */
|
|
676
|
+
getCapabilities(): ProviderCapabilities;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/** Provider capabilities information */
|
|
680
|
+
export declare interface ProviderCapabilities {
|
|
681
|
+
readonly supportsTools: boolean;
|
|
682
|
+
readonly supportsStreaming: boolean;
|
|
683
|
+
readonly supportsVision: boolean;
|
|
684
|
+
readonly supportsFunctions: boolean;
|
|
685
|
+
readonly models: readonly string[];
|
|
686
|
+
}
|
|
687
|
+
|
|
601
688
|
/** Prune result information */
|
|
602
689
|
export declare interface PruneResult {
|
|
603
690
|
readonly prunedCount: number;
|
|
@@ -649,7 +736,7 @@ export declare const RETRIEVAL_DEFAULT_LIMIT = 10;
|
|
|
649
736
|
export declare const RETRIEVAL_MAX_LIMIT = 100;
|
|
650
737
|
|
|
651
738
|
/** Retrieval tool created by factory */
|
|
652
|
-
export declare interface
|
|
739
|
+
export declare interface RetrievalToolInterface {
|
|
653
740
|
readonly schema: ToolSchema;
|
|
654
741
|
readonly handler: (args: Readonly<Record<string, unknown>>) => Promise<readonly unknown[]>;
|
|
655
742
|
}
|
|
@@ -785,11 +872,39 @@ export declare interface StoredDocument {
|
|
|
785
872
|
readonly updatedAt?: number;
|
|
786
873
|
}
|
|
787
874
|
|
|
875
|
+
/**
|
|
876
|
+
* Stream handle interface - async iteration over tokens.
|
|
877
|
+
* Provides streaming access to generation with abort control.
|
|
878
|
+
*/
|
|
879
|
+
export declare interface StreamHandleInterface {
|
|
880
|
+
/** Request identifier */
|
|
881
|
+
readonly requestId: string;
|
|
882
|
+
/** Async iteration */
|
|
883
|
+
[Symbol.asyncIterator](): AsyncIterator<string>;
|
|
884
|
+
/** Get final result */
|
|
885
|
+
result(): Promise<GenerationResult>;
|
|
886
|
+
/** Abort generation */
|
|
887
|
+
abort(): void;
|
|
888
|
+
/** Subscribe to tokens */
|
|
889
|
+
onToken(callback: (token: string) => void): Unsubscribe;
|
|
890
|
+
/** Subscribe to completion */
|
|
891
|
+
onComplete(callback: (result: GenerationResult) => void): Unsubscribe;
|
|
892
|
+
/** Subscribe to errors */
|
|
893
|
+
onError(callback: (error: Error) => void): Unsubscribe;
|
|
894
|
+
}
|
|
895
|
+
|
|
788
896
|
/** Converts subscription methods to hook callbacks for options */
|
|
789
897
|
export declare type SubscriptionToHook<T> = {
|
|
790
898
|
[K in keyof T]?: T[K] extends (callback: infer CB) => Unsubscribe ? CB : never;
|
|
791
899
|
};
|
|
792
900
|
|
|
901
|
+
/** Timeout options for generation */
|
|
902
|
+
export declare interface TimeoutOptions {
|
|
903
|
+
readonly requestMs?: number;
|
|
904
|
+
readonly streamMs?: number;
|
|
905
|
+
readonly tokenMs?: number;
|
|
906
|
+
}
|
|
907
|
+
|
|
793
908
|
/** Token budget level */
|
|
794
909
|
export declare type TokenBudgetLevel = 'ok' | 'warning' | 'critical' | 'exceeded';
|
|
795
910
|
|
|
@@ -803,6 +918,38 @@ export declare interface TokenBudgetState {
|
|
|
803
918
|
readonly level: TokenBudgetLevel;
|
|
804
919
|
}
|
|
805
920
|
|
|
921
|
+
/**
|
|
922
|
+
* Token counter interface for model-specific token counting.
|
|
923
|
+
* Provides estimation of token counts for context window management,
|
|
924
|
+
* cost estimation, and truncation decisions.
|
|
925
|
+
*/
|
|
926
|
+
export declare interface TokenCounterInterface {
|
|
927
|
+
/**
|
|
928
|
+
* Count tokens in text for specific model.
|
|
929
|
+
* @param text - Text to count tokens in
|
|
930
|
+
* @param model - Model to use for counting
|
|
931
|
+
*/
|
|
932
|
+
countTokens(text: string, model: string): number;
|
|
933
|
+
/**
|
|
934
|
+
* Count tokens in messages array.
|
|
935
|
+
* @param messages - Messages to count
|
|
936
|
+
* @param model - Model to use for counting
|
|
937
|
+
*/
|
|
938
|
+
countMessages(messages: readonly Message[], model: string): number;
|
|
939
|
+
/**
|
|
940
|
+
* Estimate if content fits in context window.
|
|
941
|
+
* @param content - Content to check
|
|
942
|
+
* @param model - Model to check against
|
|
943
|
+
* @param maxTokens - Maximum tokens allowed
|
|
944
|
+
*/
|
|
945
|
+
fitsInContext(content: string, model: string, maxTokens: number): boolean;
|
|
946
|
+
/**
|
|
947
|
+
* Get model's context window size.
|
|
948
|
+
* @param model - Model name
|
|
949
|
+
*/
|
|
950
|
+
getContextWindowSize(model: string): number | undefined;
|
|
951
|
+
}
|
|
952
|
+
|
|
806
953
|
/** Tool call from LLM response */
|
|
807
954
|
export declare interface ToolCall {
|
|
808
955
|
readonly id: string;
|
|
@@ -836,6 +983,12 @@ export declare interface ToolCallBridgeOptions {
|
|
|
836
983
|
readonly onAfterExecute?: (toolCall: ToolCall, result: unknown) => void;
|
|
837
984
|
}
|
|
838
985
|
|
|
986
|
+
/** Tool call content */
|
|
987
|
+
export declare interface ToolCallContent {
|
|
988
|
+
readonly type: 'tool_calls';
|
|
989
|
+
readonly toolCalls: readonly ToolCall[];
|
|
990
|
+
}
|
|
991
|
+
|
|
839
992
|
/**
|
|
840
993
|
* Tool format adapter interface.
|
|
841
994
|
* Converts between internal tool representations and provider-specific formats.
|
|
@@ -868,6 +1021,14 @@ export declare interface ToolResult {
|
|
|
868
1021
|
readonly error?: string;
|
|
869
1022
|
}
|
|
870
1023
|
|
|
1024
|
+
/** Tool result content */
|
|
1025
|
+
export declare interface ToolResultContent {
|
|
1026
|
+
readonly type: 'tool_result';
|
|
1027
|
+
readonly callId: string;
|
|
1028
|
+
readonly name: string;
|
|
1029
|
+
readonly result: unknown;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
871
1032
|
/** Tool schema definition */
|
|
872
1033
|
export declare interface ToolSchema {
|
|
873
1034
|
readonly name: string;
|
|
@@ -942,6 +1103,13 @@ export declare function unwrap<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
|
942
1103
|
*/
|
|
943
1104
|
export declare function unwrapOrThrow<T, E>(result: Result<T, E>): T;
|
|
944
1105
|
|
|
1106
|
+
/** Token usage statistics */
|
|
1107
|
+
export declare interface UsageStats {
|
|
1108
|
+
readonly promptTokens: number;
|
|
1109
|
+
readonly completionTokens: number;
|
|
1110
|
+
readonly totalTokens: number;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
945
1113
|
/** VectorStore metadata for persistence */
|
|
946
1114
|
export declare interface VectorStoreMetadata {
|
|
947
1115
|
readonly dimensions: number;
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ function b(e) {
|
|
|
11
11
|
function S(e) {
|
|
12
12
|
return { ok: !0, value: e };
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function I(e) {
|
|
15
15
|
return { ok: !1, error: e };
|
|
16
16
|
}
|
|
17
17
|
function F(e) {
|
|
@@ -32,7 +32,7 @@ function B(e, t) {
|
|
|
32
32
|
return e.ok ? S(t(e.value)) : e;
|
|
33
33
|
}
|
|
34
34
|
function G(e, t) {
|
|
35
|
-
return e.ok ? e :
|
|
35
|
+
return e.ok ? e : I(t(e.error));
|
|
36
36
|
}
|
|
37
37
|
function O(e, t) {
|
|
38
38
|
return e.ok ? t(e.value) : e;
|
|
@@ -41,11 +41,11 @@ async function $(e) {
|
|
|
41
41
|
const s = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", s);
|
|
42
42
|
return Array.from(new Uint8Array(a)).map((o) => o.toString(16).padStart(2, "0")).join("");
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function k(e) {
|
|
45
45
|
return typeof e == "object" && e !== null && "id" in e && "name" in e && "arguments" in e;
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
return
|
|
47
|
+
function l(e, t, s, a) {
|
|
48
|
+
return s.includes(e) ? !0 : a !== void 0 && !a.includes(t);
|
|
49
49
|
}
|
|
50
50
|
function M(e) {
|
|
51
51
|
return {
|
|
@@ -100,7 +100,7 @@ function j(e) {
|
|
|
100
100
|
}
|
|
101
101
|
return {
|
|
102
102
|
execute(r) {
|
|
103
|
-
return
|
|
103
|
+
return k(r) ? u(r) : Promise.all(
|
|
104
104
|
r.map((n) => u(n))
|
|
105
105
|
);
|
|
106
106
|
},
|
|
@@ -164,7 +164,7 @@ function N(e) {
|
|
|
164
164
|
onlyFromPages: o
|
|
165
165
|
} = e;
|
|
166
166
|
return async function(r, n) {
|
|
167
|
-
return
|
|
167
|
+
return l(r, n, c, o) || !t.isDirty() ? !0 : Promise.resolve(s(a));
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
170
|
function V(e) {
|
|
@@ -221,16 +221,16 @@ export {
|
|
|
221
221
|
H as createRetrievalTool,
|
|
222
222
|
V as createSessionPersistence,
|
|
223
223
|
j as createToolCallBridge,
|
|
224
|
-
|
|
224
|
+
I as err,
|
|
225
225
|
M as formatScoredResult,
|
|
226
226
|
b as isEcosystemError,
|
|
227
227
|
P as isErr,
|
|
228
228
|
F as isOk,
|
|
229
|
-
|
|
229
|
+
k as isToolCall,
|
|
230
230
|
B as map,
|
|
231
231
|
G as mapErr,
|
|
232
232
|
S as ok,
|
|
233
|
-
|
|
233
|
+
l as shouldSkipFormGuard,
|
|
234
234
|
q as unwrap,
|
|
235
235
|
U as unwrapOrThrow
|
|
236
236
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/helpers.ts","../src/constants.ts","../src/factories.ts"],"sourcesContent":["/**\n * @mikesaintsg/core\n *\n * Base error class and utilities for the ecosystem.\n */\n// ============================================================================\n// Base Ecosystem Error\n// ============================================================================\n/**\n * Base error class for all ecosystem errors.\n * All package-specific errors should extend this class.\n *\n * @example\n * ```ts\n * class StorageError extends EcosystemError {\n * readonly code: StorageErrorCode\n *\n * constructor(code: StorageErrorCode, message: string, cause?: Error) {\n * super(message, cause)\n * this.code = code\n * }\n * }\n * ```\n */\nexport abstract class EcosystemError extends Error {\n\t/** Error code for programmatic handling */\n\tabstract readonly code: string\n\t/** Original error that caused this one */\n\toverride readonly cause: Error | undefined\n\n\tconstructor(message: string, cause?: Error) {\n\t\tsuper(message)\n\t\tthis.name = this.constructor.name\n\t\tthis.cause = cause\n\t}\n}\n/**\n * Type guard for ecosystem errors.\n *\n * @param error - The value to check\n * @returns True if the error is an EcosystemError\n *\n * @example\n * ```ts\n * try {\n * await someOperation()\n * } catch (error) {\n * if (isEcosystemError(error)) {\n * console.log('Code:', error.code)\n * }\n * }\n * ```\n */\nexport function isEcosystemError(error: unknown): error is EcosystemError {\n\treturn error instanceof EcosystemError\n}\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Helper functions and type guards.\r\n */\r\n\r\nimport type { Ok, Err, Result, ContentHash, ScoredResult } from './types.js'\r\n\r\n// ============================================================================\r\n// Result Pattern Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a success result.\r\n *\r\n * @param value - The success value\r\n * @returns An Ok result containing the value\r\n *\r\n * @example\r\n * ```ts\r\n * const result = ok(42)\r\n * // result.ok === true\r\n * // result.value === 42\r\n * ```\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n\treturn { ok: true, value }\r\n}\r\n\r\n/**\r\n * Create a failure result.\r\n *\r\n * @param error - The error value\r\n * @returns An Err result containing the error\r\n *\r\n * @example\r\n * ```ts\r\n * const result = err('NOT_FOUND')\r\n * // result.ok === false\r\n * // result.error === 'NOT_FOUND'\r\n * ```\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n\treturn { ok: false, error }\r\n}\r\n\r\n/**\r\n * Check if a result is a success.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Ok, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = ok(42)\r\n * if (isOk(result)) {\r\n * console.log(result.value) // TypeScript knows result is Ok<number>\r\n * }\r\n * ```\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n\treturn result.ok === true\r\n}\r\n\r\n/**\r\n * Check if a result is a failure.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Err, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = err('NOT_FOUND')\r\n * if (isErr(result)) {\r\n * console.log(result.error) // TypeScript knows result is Err<string>\r\n * }\r\n * ```\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n\treturn !result.ok\r\n}\r\n\r\n/**\r\n * Unwrap a result, returning the value or a default.\r\n *\r\n * @param result - The result to unwrap\r\n * @param defaultValue - Value to return if result is an error\r\n * @returns The success value or the default value\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrap(ok(42), 0) // 42\r\n * const fallback = unwrap(err('oops'), 0) // 0\r\n * ```\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n\treturn result.ok ? result.value : defaultValue\r\n}\r\n\r\n/**\r\n * Unwrap a result, throwing if it's an error.\r\n *\r\n * @param result - The result to unwrap\r\n * @returns The success value\r\n * @throws The error if result is Err\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrapOrThrow(ok(42)) // 42\r\n * unwrapOrThrow(err(new Error('oops'))) // throws Error('oops')\r\n * ```\r\n */\r\nexport function unwrapOrThrow<T, E>(result: Result<T, E>): T {\r\n\tif (result.ok) {\r\n\t\treturn result.value\r\n\t}\r\n\tif (result.error instanceof Error) {\r\n\t\tthrow result.error\r\n\t}\r\n\tthrow new Error(String(result.error))\r\n}\r\n\r\n/**\r\n * Map a function over a success value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the success value\r\n * @returns A new result with the mapped value, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const doubled = map(ok(5), x => x * 2) // ok(10)\r\n * const failed = map(err('oops'), x => x * 2) // err('oops')\r\n * ```\r\n */\r\nexport function map<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => U,\r\n): Result<U, E> {\r\n\treturn result.ok ? ok(fn(result.value)) : result\r\n}\r\n\r\n/**\r\n * Map a function over an error value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the error value\r\n * @returns A new result with the mapped error, or the original value\r\n *\r\n * @example\r\n * ```ts\r\n * const wrapped = mapErr(err('oops'), e => new Error(e)) // err(Error('oops'))\r\n * const unchanged = mapErr(ok(42), e => new Error(e)) // ok(42)\r\n * ```\r\n */\r\nexport function mapErr<T, E, F>(\r\n\tresult: Result<T, E>,\r\n\tfn: (error: E) => F,\r\n): Result<T, F> {\r\n\treturn result.ok ? result : err(fn(result.error))\r\n}\r\n\r\n/**\r\n * Chain results (flatMap). Apply a function that returns a Result to a success value.\r\n *\r\n * @param result - The result to chain\r\n * @param fn - Function returning a new Result\r\n * @returns The result of applying fn, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const parsed = chain(ok('42'), s => {\r\n * const n = parseInt(s, 10)\r\n * return isNaN(n) ? err('PARSE_ERROR') : ok(n)\r\n * })\r\n * // parsed = ok(42)\r\n * ```\r\n */\r\nexport function chain<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => Result<U, E>,\r\n): Result<U, E> {\r\n\treturn result.ok ? fn(result.value) : result\r\n}\r\n\r\n// ============================================================================\r\n// Content Hashing Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Compute a SHA-256 content hash for text.\r\n *\r\n * @param text - The text to hash\r\n * @returns A hex string content hash\r\n *\r\n * @example\r\n * ```ts\r\n * const hash = await computeContentHash('Hello, world!')\r\n * // hash = 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'\r\n * ```\r\n */\r\nexport async function computeContentHash(text: string): Promise<ContentHash> {\r\n\tconst encoder = new TextEncoder()\r\n\tconst data = encoder.encode(text)\r\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\r\n\tconst hashArray = Array.from(new Uint8Array(hashBuffer))\r\n\treturn hashArray.map(b => b.toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\n// ============================================================================\r\n// Bridge Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a value is a single ToolCall (not an array).\r\n *\r\n * @param value - Value to check\r\n * @returns True if the value is a single ToolCall\r\n */\r\nexport function isToolCall(value: unknown): value is { id: string; name: string; arguments: unknown } {\r\n\treturn (\r\n\t\ttypeof value === 'object' &&\r\n\t\tvalue !== null &&\r\n\t\t'id' in value &&\r\n\t\t'name' in value &&\r\n\t\t'arguments' in value\r\n\t)\r\n}\r\n\r\n/**\r\n * Determine if form dirty guard should be skipped for a navigation.\r\n *\r\n * @param to - Target page\r\n * @param from - Source page\r\n * @param excludePages - Pages to exclude from guard\r\n * @param onlyFromPages - Only guard from these pages (if specified)\r\n * @returns True if guard should be skipped\r\n */\r\nexport function shouldSkipFormGuard<TPage extends string>(\r\n\tto: TPage,\r\n\tfrom: TPage,\r\n\texcludePages: readonly TPage[],\r\n\tonlyFromPages: readonly TPage[] | undefined,\r\n): boolean {\r\n\t// Skip if navigating to excluded page\r\n\tif (excludePages.includes(to)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\t// Skip if from page is not in onlyFromPages (if specified)\r\n\tif (onlyFromPages !== undefined && !onlyFromPages.includes(from)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\treturn false\r\n}\r\n\r\n/**\r\n * Default result formatter for retrieval tools.\r\n * Returns content, score, and metadata.\r\n *\r\n * @param result - Scored result to format\r\n * @returns Formatted result object\r\n */\r\nexport function formatScoredResult(result: ScoredResult): unknown {\r\n\treturn {\r\n\t\tcontent: result.content,\r\n\t\tscore: result.score,\r\n\t\tmetadata: result.metadata,\r\n\t}\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Shared constants for the core library.\r\n */\r\n\r\n// ============================================================================\r\n// Bridge Constants\r\n// ============================================================================\r\n\r\n/** Default timeout for bridge operations in milliseconds */\r\nexport const BRIDGE_DEFAULT_TIMEOUT = 30000\r\n\r\n/** Default retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_DEFAULT_LIMIT = 10\r\n\r\n/** Maximum retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_MAX_LIMIT = 100\r\n\r\n/** Default form dirty guard message */\r\nexport const FORM_DIRTY_DEFAULT_MESSAGE = 'You have unsaved changes. Are you sure you want to leave?'\r\n","/**\n * @mikesaintsg/core\n *\n * Factory functions for creating bridge instances.\n */\n\nimport type {\n\tToolCall,\n\tToolResult,\n\tToolCallBridgeOptions,\n\tToolCallBridgeInterface,\n\tRetrievalToolOptions,\n\tRetrievalToolCreated,\n\tToolSchema,\n\tJSONSchema7,\n\tFormDirtyGuardOptions,\n\tNavigationGuard,\n\tSessionPersistenceOptions,\n\tSessionPersistenceInterface,\n\tSerializableSession,\n\tSerializedSession,\n} from './types.js'\nimport {\n\tBRIDGE_DEFAULT_TIMEOUT,\n\tRETRIEVAL_DEFAULT_LIMIT,\n\tRETRIEVAL_MAX_LIMIT,\n\tFORM_DIRTY_DEFAULT_MESSAGE,\n} from './constants.js'\nimport {\n\tisToolCall,\n\tshouldSkipFormGuard,\n\tformatScoredResult,\n} from './helpers.js'\n\n// ============================================================================\n// Tool Call Bridge Factory\n// ============================================================================\n\n/**\n * Create a tool call bridge.\n *\n * @param options - Bridge configuration options\n * @returns A tool call bridge instance\n *\n * @example\n * ```ts\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createToolCallBridge } from '@mikesaintsg/core'\n *\n * const registry = createToolRegistry()\n * registry.register(weatherTool)\n *\n * const bridge = createToolCallBridge({\n * registry,\n * timeout: 30000,\n * onError: (error, toolCall) => console.error(`Tool ${toolCall.name} failed:`, error),\n * })\n *\n * // Execute tool calls from LLM response\n * const results = await bridge.execute(response.toolCalls)\n * ```\n */\nexport function createToolCallBridge(\n\toptions: ToolCallBridgeOptions,\n): ToolCallBridgeInterface {\n\tconst {\n\t\tregistry,\n\t\ttimeout = BRIDGE_DEFAULT_TIMEOUT,\n\t\tonError,\n\t\tonBeforeExecute,\n\t\tonAfterExecute,\n\t} = options\n\n\tasync function executeWithTimeout(toolCall: ToolCall): Promise<ToolResult> {\n\t\t// Check if tool exists\n\t\tif (!registry.has(toolCall.name)) {\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `Tool not found: ${toolCall.name}`,\n\t\t\t}\n\t\t}\n\n\t\t// Call lifecycle hook\n\t\tonBeforeExecute?.(toolCall)\n\n\t\ttry {\n\t\t\t// Create timeout promise\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\treject(new Error(`Tool execution timed out after ${timeout}ms`))\n\t\t\t\t}, timeout)\n\t\t\t})\n\n\t\t\t// Execute tool with timeout\n\t\t\tconst value = await Promise.race([\n\t\t\t\tregistry.execute(toolCall.name, toolCall.arguments),\n\t\t\t\ttimeoutPromise,\n\t\t\t])\n\n\t\t\t// Call lifecycle hook\n\t\t\tonAfterExecute?.(toolCall, value)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: true,\n\t\t\t\tvalue,\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Call error hook\n\t\t\tonError?.(error, toolCall)\n\n\t\t\tconst errorMessage = error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\texecute(toolCallOrCalls: ToolCall | readonly ToolCall[]) {\n\t\t\tif (isToolCall(toolCallOrCalls)) {\n\t\t\t\treturn executeWithTimeout(toolCallOrCalls)\n\t\t\t}\n\t\t\treturn Promise.all(\n\t\t\t\t(toolCallOrCalls).map(tc => executeWithTimeout(tc)),\n\t\t\t)\n\t\t},\n\n\t\thasTool(name: string): boolean {\n\t\t\treturn registry.has(name)\n\t\t},\n\t} as ToolCallBridgeInterface\n}\n\n// ============================================================================\n// Retrieval Tool Factory\n// ============================================================================\n\n/**\n * Create a retrieval tool for use with contextprotocol tool registry.\n *\n * @param options - Retrieval tool configuration options\n * @returns A tool schema and handler for registration\n *\n * @example\n * ```ts\n * import { createVectorStore } from '@mikesaintsg/vectorstore'\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createRetrievalTool } from '@mikesaintsg/core'\n *\n * const vectorStore = createVectorStore({ ... })\n * const registry = createToolRegistry()\n *\n * const { schema, handler } = createRetrievalTool({\n * vectorStore,\n * name: 'search_docs',\n * description: 'Search documentation for relevant information',\n * defaultLimit: 5,\n * scoreThreshold: 0.7,\n * })\n *\n * registry.register({ ...schema, execute: handler })\n * ```\n */\nexport function createRetrievalTool<TMetadata = unknown>(\n\toptions: RetrievalToolOptions<TMetadata>,\n): RetrievalToolCreated {\n\tconst {\n\t\tvectorStore,\n\t\tname,\n\t\tdescription,\n\t\tdefaultLimit = RETRIEVAL_DEFAULT_LIMIT,\n\t\tmaxLimit = RETRIEVAL_MAX_LIMIT,\n\t\tscoreThreshold,\n\t\tformatResult = formatScoredResult,\n\t\textendParameters = {},\n\t\tbuildFilter,\n\t} = options\n\n\t// Build tool schema parameters\n\tconst parameters: JSONSchema7 = {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tquery: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'The search query to find relevant documents',\n\t\t\t},\n\t\t\tlimit: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tdescription: `Maximum number of results to return (default: ${defaultLimit}, max: ${maxLimit})`,\n\t\t\t\tminimum: 1,\n\t\t\t\tmaximum: maxLimit,\n\t\t\t\tdefault: defaultLimit,\n\t\t\t},\n\t\t\t...extendParameters,\n\t\t},\n\t\trequired: ['query'],\n\t}\n\n\tconst schema: ToolSchema = {\n\t\tname,\n\t\tdescription,\n\t\tparameters,\n\t}\n\n\tasync function handler(\n\t\targs: Readonly<Record<string, unknown>>,\n\t): Promise<readonly unknown[]> {\n\t\tconst query = args.query\n\t\tif (typeof query !== 'string' || query.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\tconst requestedLimit = args.limit\n\t\tlet limit = defaultLimit\n\t\tif (typeof requestedLimit === 'number' && Number.isInteger(requestedLimit)) {\n\t\t\tlimit = Math.min(Math.max(1, requestedLimit), maxLimit)\n\t\t}\n\n\t\t// Build filter if provided\n\t\tconst filter = buildFilter?.(args)\n\n\t\t// Search vectorstore - only include filter if defined\n\t\tconst searchOptions = filter !== undefined\n\t\t\t? { limit, filter }\n\t\t\t: { limit }\n\t\tconst results = await vectorStore.search(query, searchOptions)\n\n\t\t// Filter by score threshold\n\t\tlet filteredResults = results\n\t\tif (scoreThreshold !== undefined) {\n\t\t\tfilteredResults = results.filter(r => r.score >= scoreThreshold)\n\t\t}\n\n\t\t// Format results\n\t\treturn filteredResults.map(formatResult)\n\t}\n\n\treturn { schema, handler }\n}\n\n// ============================================================================\n// Form Dirty Guard Factory\n// ============================================================================\n\n/**\n * Create a navigation guard that prevents leaving when form is dirty.\n *\n * @param options - Form dirty guard configuration options\n * @returns A navigation guard function\n *\n * @example\n * ```ts\n * import { createForm } from '@mikesaintsg/form'\n * import { createFormDirtyGuard } from '@mikesaintsg/core'\n *\n * const form = createForm({ ... })\n *\n * const guard = createFormDirtyGuard({\n * form,\n * confirmFn: (message) => window.confirm(message),\n * message: 'You have unsaved changes. Continue?',\n * excludePages: ['settings'],\n * })\n *\n * // Use with router\n * router.beforeNavigate(guard)\n * ```\n */\nexport function createFormDirtyGuard<TFormData = unknown, TPage extends string = string>(\n\toptions: FormDirtyGuardOptions<TFormData, TPage>,\n): NavigationGuard<TPage> {\n\tconst {\n\t\tform,\n\t\tconfirmFn,\n\t\tmessage = FORM_DIRTY_DEFAULT_MESSAGE,\n\t\texcludePages = [],\n\t\tonlyFromPages,\n\t} = options\n\n\treturn async function guard(to: TPage, from: TPage): Promise<boolean> {\n\t\t// Check if we should skip guard for this navigation\n\t\tif (shouldSkipFormGuard(to, from, excludePages, onlyFromPages)) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If form is not dirty, allow navigation\n\t\tif (!form.isDirty()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Form is dirty, ask for confirmation\n\t\treturn Promise.resolve(confirmFn(message))\n\t}\n}\n\n// ============================================================================\n// Session Persistence Factory\n// ============================================================================\n\n/**\n * Create a session persistence adapter for storing inference sessions.\n *\n * @param options - Session persistence configuration options\n * @returns A session persistence instance\n *\n * @example\n * ```ts\n * import { createDatabase } from '@mikesaintsg/indexeddb'\n * import { createSessionPersistence } from '@mikesaintsg/core'\n *\n * const db = await createDatabase({ name: 'sessions' })\n * const persistence = createSessionPersistence({\n * database: db,\n * storeName: 'chat_sessions',\n * autoprune: 7 * 24 * 60 * 60 * 1000, // 7 days\n * })\n *\n * // Save session\n * await persistence.save('session-1', session)\n *\n * // Load session\n * const savedSession = await persistence.load('session-1')\n * ```\n */\nexport function createSessionPersistence(\n\toptions: SessionPersistenceOptions,\n): SessionPersistenceInterface {\n\tconst {\n\t\tdatabase,\n\t\tstoreName,\n\t\tautoprune,\n\t\tonSaveError,\n\t} = options\n\n\tconst store = database.store<SerializedSession>(storeName)\n\n\tasync function pruneOldSessions(maxAgeMs: number): Promise<number> {\n\t\tconst now = Date.now()\n\t\tconst cutoff = now - maxAgeMs\n\n\t\tconst allSessions = await store.all()\n\t\tlet prunedCount = 0\n\n\t\tfor (const session of allSessions) {\n\t\t\tif (session.updatedAt < cutoff) {\n\t\t\t\tawait store.remove(session.id)\n\t\t\t\tprunedCount++\n\t\t\t}\n\t\t}\n\n\t\treturn prunedCount\n\t}\n\n\t// Auto-prune on creation if configured\n\tif (autoprune !== undefined && autoprune > 0) {\n\t\tvoid pruneOldSessions(autoprune)\n\t}\n\n\treturn {\n\t\tasync save(id: string, session: SerializableSession): Promise<void> {\n\t\t\ttry {\n\t\t\t\tconst serialized: SerializedSession = {\n\t\t\t\t\tid,\n\t\t\t\t\tmessages: [...session.getMessages()],\n\t\t\t\t\tmetadata: session.getMetadata(),\n\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t}\n\n\t\t\t\tawait store.set(serialized, id)\n\t\t\t} catch (error) {\n\t\t\t\tonSaveError?.(error, id)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\n\t\tasync load(id: string): Promise<SerializedSession | undefined> {\n\t\t\treturn store.get(id)\n\t\t},\n\n\t\tasync delete(id: string): Promise<void> {\n\t\t\tawait store.remove(id)\n\t\t},\n\n\t\tasync list(): Promise<readonly string[]> {\n\t\t\tconst allSessions = await store.all()\n\t\t\treturn allSessions.map(s => s.id)\n\t\t},\n\n\t\tasync prune(maxAgeMs: number): Promise<number> {\n\t\t\treturn pruneOldSessions(maxAgeMs)\n\t\t},\n\t}\n}\n"],"names":["EcosystemError","message","cause","isEcosystemError","error","ok","value","err","isOk","result","isErr","unwrap","defaultValue","unwrapOrThrow","map","fn","mapErr","chain","computeContentHash","text","data","hashBuffer","b","isToolCall","shouldSkipFormGuard","to","from","excludePages","onlyFromPages","formatScoredResult","BRIDGE_DEFAULT_TIMEOUT","RETRIEVAL_DEFAULT_LIMIT","RETRIEVAL_MAX_LIMIT","FORM_DIRTY_DEFAULT_MESSAGE","createToolCallBridge","options","registry","timeout","onError","onBeforeExecute","onAfterExecute","executeWithTimeout","toolCall","timeoutPromise","_","reject","errorMessage","toolCallOrCalls","tc","name","createRetrievalTool","vectorStore","description","defaultLimit","maxLimit","scoreThreshold","formatResult","extendParameters","buildFilter","parameters","schema","handler","args","query","requestedLimit","limit","filter","searchOptions","results","filteredResults","r","createFormDirtyGuard","form","confirmFn","createSessionPersistence","database","storeName","autoprune","onSaveError","store","pruneOldSessions","maxAgeMs","cutoff","allSessions","prunedCount","session","id","serialized","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/helpers.ts","../src/constants.ts","../src/factories.ts"],"sourcesContent":["/**\n * @mikesaintsg/core\n *\n * Base error class and utilities for the ecosystem.\n */\n// ============================================================================\n// Base Ecosystem Error\n// ============================================================================\n/**\n * Base error class for all ecosystem errors.\n * All package-specific errors should extend this class.\n *\n * @example\n * ```ts\n * class StorageError extends EcosystemError {\n * readonly code: StorageErrorCode\n *\n * constructor(code: StorageErrorCode, message: string, cause?: Error) {\n * super(message, cause)\n * this.code = code\n * }\n * }\n * ```\n */\nexport abstract class EcosystemError extends Error {\n\t/** Error code for programmatic handling */\n\tabstract readonly code: string\n\t/** Original error that caused this one */\n\toverride readonly cause: Error | undefined\n\n\tconstructor(message: string, cause?: Error) {\n\t\tsuper(message)\n\t\tthis.name = this.constructor.name\n\t\tthis.cause = cause\n\t}\n}\n/**\n * Type guard for ecosystem errors.\n *\n * @param error - The value to check\n * @returns True if the error is an EcosystemError\n *\n * @example\n * ```ts\n * try {\n * await someOperation()\n * } catch (error) {\n * if (isEcosystemError(error)) {\n * console.log('Code:', error.code)\n * }\n * }\n * ```\n */\nexport function isEcosystemError(error: unknown): error is EcosystemError {\n\treturn error instanceof EcosystemError\n}\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Helper functions and type guards.\r\n */\r\n\r\nimport type { Ok, Err, Result, ContentHash, ScoredResult } from './types.js'\r\n\r\n// ============================================================================\r\n// Result Pattern Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a success result.\r\n *\r\n * @param value - The success value\r\n * @returns An Ok result containing the value\r\n *\r\n * @example\r\n * ```ts\r\n * const result = ok(42)\r\n * // result.ok === true\r\n * // result.value === 42\r\n * ```\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n\treturn { ok: true, value }\r\n}\r\n\r\n/**\r\n * Create a failure result.\r\n *\r\n * @param error - The error value\r\n * @returns An Err result containing the error\r\n *\r\n * @example\r\n * ```ts\r\n * const result = err('NOT_FOUND')\r\n * // result.ok === false\r\n * // result.error === 'NOT_FOUND'\r\n * ```\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n\treturn { ok: false, error }\r\n}\r\n\r\n/**\r\n * Check if a result is a success.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Ok, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = ok(42)\r\n * if (isOk(result)) {\r\n * console.log(result.value) // TypeScript knows result is Ok<number>\r\n * }\r\n * ```\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n\treturn result.ok === true\r\n}\r\n\r\n/**\r\n * Check if a result is a failure.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Err, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = err('NOT_FOUND')\r\n * if (isErr(result)) {\r\n * console.log(result.error) // TypeScript knows result is Err<string>\r\n * }\r\n * ```\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n\treturn !result.ok\r\n}\r\n\r\n/**\r\n * Unwrap a result, returning the value or a default.\r\n *\r\n * @param result - The result to unwrap\r\n * @param defaultValue - Value to return if result is an error\r\n * @returns The success value or the default value\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrap(ok(42), 0) // 42\r\n * const fallback = unwrap(err('oops'), 0) // 0\r\n * ```\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n\treturn result.ok ? result.value : defaultValue\r\n}\r\n\r\n/**\r\n * Unwrap a result, throwing if it's an error.\r\n *\r\n * @param result - The result to unwrap\r\n * @returns The success value\r\n * @throws The error if result is Err\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrapOrThrow(ok(42)) // 42\r\n * unwrapOrThrow(err(new Error('oops'))) // throws Error('oops')\r\n * ```\r\n */\r\nexport function unwrapOrThrow<T, E>(result: Result<T, E>): T {\r\n\tif (result.ok) {\r\n\t\treturn result.value\r\n\t}\r\n\tif (result.error instanceof Error) {\r\n\t\tthrow result.error\r\n\t}\r\n\tthrow new Error(String(result.error))\r\n}\r\n\r\n/**\r\n * Map a function over a success value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the success value\r\n * @returns A new result with the mapped value, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const doubled = map(ok(5), x => x * 2) // ok(10)\r\n * const failed = map(err('oops'), x => x * 2) // err('oops')\r\n * ```\r\n */\r\nexport function map<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => U,\r\n): Result<U, E> {\r\n\treturn result.ok ? ok(fn(result.value)) : result\r\n}\r\n\r\n/**\r\n * Map a function over an error value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the error value\r\n * @returns A new result with the mapped error, or the original value\r\n *\r\n * @example\r\n * ```ts\r\n * const wrapped = mapErr(err('oops'), e => new Error(e)) // err(Error('oops'))\r\n * const unchanged = mapErr(ok(42), e => new Error(e)) // ok(42)\r\n * ```\r\n */\r\nexport function mapErr<T, E, F>(\r\n\tresult: Result<T, E>,\r\n\tfn: (error: E) => F,\r\n): Result<T, F> {\r\n\treturn result.ok ? result : err(fn(result.error))\r\n}\r\n\r\n/**\r\n * Chain results (flatMap). Apply a function that returns a Result to a success value.\r\n *\r\n * @param result - The result to chain\r\n * @param fn - Function returning a new Result\r\n * @returns The result of applying fn, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const parsed = chain(ok('42'), s => {\r\n * const n = parseInt(s, 10)\r\n * return isNaN(n) ? err('PARSE_ERROR') : ok(n)\r\n * })\r\n * // parsed = ok(42)\r\n * ```\r\n */\r\nexport function chain<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => Result<U, E>,\r\n): Result<U, E> {\r\n\treturn result.ok ? fn(result.value) : result\r\n}\r\n\r\n// ============================================================================\r\n// Content Hashing Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Compute a SHA-256 content hash for text.\r\n *\r\n * @param text - The text to hash\r\n * @returns A hex string content hash\r\n *\r\n * @example\r\n * ```ts\r\n * const hash = await computeContentHash('Hello, world!')\r\n * // hash = 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'\r\n * ```\r\n */\r\nexport async function computeContentHash(text: string): Promise<ContentHash> {\r\n\tconst encoder = new TextEncoder()\r\n\tconst data = encoder.encode(text)\r\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\r\n\tconst hashArray = Array.from(new Uint8Array(hashBuffer))\r\n\treturn hashArray.map(b => b.toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\n// ============================================================================\r\n// Bridge Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a value is a single ToolCall (not an array).\r\n *\r\n * @param value - Value to check\r\n * @returns True if the value is a single ToolCall\r\n */\r\nexport function isToolCall(value: unknown): value is { id: string; name: string; arguments: unknown } {\r\n\treturn (\r\n\t\ttypeof value === 'object' &&\r\n\t\tvalue !== null &&\r\n\t\t'id' in value &&\r\n\t\t'name' in value &&\r\n\t\t'arguments' in value\r\n\t)\r\n}\r\n\r\n/**\r\n * Determine if form dirty guard should be skipped for a navigation.\r\n *\r\n * @param to - Target page\r\n * @param from - Source page\r\n * @param excludePages - Pages to exclude from guard\r\n * @param onlyFromPages - Only guard from these pages (if specified)\r\n * @returns True if guard should be skipped\r\n */\r\nexport function shouldSkipFormGuard<TPage extends string>(\r\n\tto: TPage,\r\n\tfrom: TPage,\r\n\texcludePages: readonly TPage[],\r\n\tonlyFromPages: readonly TPage[] | undefined,\r\n): boolean {\r\n\t// Skip if navigating to excluded page\r\n\tif (excludePages.includes(to)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\t// Skip if from page is not in onlyFromPages (if specified)\r\n\treturn onlyFromPages !== undefined && !onlyFromPages.includes(from)\r\n}\r\n\r\n/**\r\n * Default result formatter for retrieval tools.\r\n * Returns content, score, and metadata.\r\n *\r\n * @param result - Scored result to format\r\n * @returns Formatted result object\r\n */\r\nexport function formatScoredResult(result: ScoredResult): unknown {\r\n\treturn {\r\n\t\tcontent: result.content,\r\n\t\tscore: result.score,\r\n\t\tmetadata: result.metadata,\r\n\t}\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Shared constants for the core library.\r\n */\r\n\r\n// ============================================================================\r\n// Bridge Constants\r\n// ============================================================================\r\n\r\n/** Default timeout for bridge operations in milliseconds */\r\nexport const BRIDGE_DEFAULT_TIMEOUT = 30000\r\n\r\n/** Default retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_DEFAULT_LIMIT = 10\r\n\r\n/** Maximum retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_MAX_LIMIT = 100\r\n\r\n/** Default form dirty guard message */\r\nexport const FORM_DIRTY_DEFAULT_MESSAGE = 'You have unsaved changes. Are you sure you want to leave?'\r\n","/**\n * @mikesaintsg/core\n *\n * Factory functions for creating bridge instances.\n */\n\nimport type {\n\tToolCall,\n\tToolResult,\n\tToolCallBridgeOptions,\n\tToolCallBridgeInterface,\n\tRetrievalToolOptions,\n\tRetrievalToolInterface,\n\tToolSchema,\n\tJSONSchema7,\n\tFormDirtyGuardOptions,\n\tNavigationGuard,\n\tSessionPersistenceOptions,\n\tSessionPersistenceInterface,\n\tSerializableSession,\n\tSerializedSession,\n} from './types.js'\nimport {\n\tBRIDGE_DEFAULT_TIMEOUT,\n\tRETRIEVAL_DEFAULT_LIMIT,\n\tRETRIEVAL_MAX_LIMIT,\n\tFORM_DIRTY_DEFAULT_MESSAGE,\n} from './constants.js'\nimport {\n\tisToolCall,\n\tshouldSkipFormGuard,\n\tformatScoredResult,\n} from './helpers.js'\n\n// ============================================================================\n// Tool Call Bridge Factory\n// ============================================================================\n\n/**\n * Create a tool call bridge.\n *\n * @param options - Bridge configuration options\n * @returns A tool call bridge instance\n *\n * @example\n * ```ts\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createToolCallBridge } from '@mikesaintsg/core'\n *\n * const registry = createToolRegistry()\n * registry.register(weatherTool)\n *\n * const bridge = createToolCallBridge({\n * registry,\n * timeout: 30000,\n * onError: (error, toolCall) => console.error(`Tool ${toolCall.name} failed:`, error),\n * })\n *\n * // Execute tool calls from LLM response\n * const results = await bridge.execute(response.toolCalls)\n * ```\n */\nexport function createToolCallBridge(\n\toptions: ToolCallBridgeOptions,\n): ToolCallBridgeInterface {\n\tconst {\n\t\tregistry,\n\t\ttimeout = BRIDGE_DEFAULT_TIMEOUT,\n\t\tonError,\n\t\tonBeforeExecute,\n\t\tonAfterExecute,\n\t} = options\n\n\tasync function executeWithTimeout(toolCall: ToolCall): Promise<ToolResult> {\n\t\t// Check if tool exists\n\t\tif (!registry.has(toolCall.name)) {\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `Tool not found: ${toolCall.name}`,\n\t\t\t}\n\t\t}\n\n\t\t// Call lifecycle hook\n\t\tonBeforeExecute?.(toolCall)\n\n\t\ttry {\n\t\t\t// Create timeout promise\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\treject(new Error(`Tool execution timed out after ${timeout}ms`))\n\t\t\t\t}, timeout)\n\t\t\t})\n\n\t\t\t// Execute tool with timeout\n\t\t\tconst value = await Promise.race([\n\t\t\t\tregistry.execute(toolCall.name, toolCall.arguments),\n\t\t\t\ttimeoutPromise,\n\t\t\t])\n\n\t\t\t// Call lifecycle hook\n\t\t\tonAfterExecute?.(toolCall, value)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: true,\n\t\t\t\tvalue,\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Call error hook\n\t\t\tonError?.(error, toolCall)\n\n\t\t\tconst errorMessage = error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\texecute(toolCallOrCalls: ToolCall | readonly ToolCall[]) {\n\t\t\tif (isToolCall(toolCallOrCalls)) {\n\t\t\t\treturn executeWithTimeout(toolCallOrCalls)\n\t\t\t}\n\t\t\treturn Promise.all(\n\t\t\t\t(toolCallOrCalls).map(tc => executeWithTimeout(tc)),\n\t\t\t)\n\t\t},\n\n\t\thasTool(name: string): boolean {\n\t\t\treturn registry.has(name)\n\t\t},\n\t} as ToolCallBridgeInterface\n}\n\n// ============================================================================\n// Retrieval Tool Factory\n// ============================================================================\n\n/**\n * Create a retrieval tool for use with contextprotocol tool registry.\n *\n * @param options - Retrieval tool configuration options\n * @returns A tool schema and handler for registration\n *\n * @example\n * ```ts\n * import { createVectorStore } from '@mikesaintsg/vectorstore'\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createRetrievalTool } from '@mikesaintsg/core'\n *\n * const vectorStore = createVectorStore({ ... })\n * const registry = createToolRegistry()\n *\n * const { schema, handler } = createRetrievalTool({\n * vectorStore,\n * name: 'search_docs',\n * description: 'Search documentation for relevant information',\n * defaultLimit: 5,\n * scoreThreshold: 0.7,\n * })\n *\n * registry.register({ ...schema, execute: handler })\n * ```\n */\nexport function createRetrievalTool<TMetadata = unknown>(\n\toptions: RetrievalToolOptions<TMetadata>,\n): RetrievalToolInterface {\n\tconst {\n\t\tvectorStore,\n\t\tname,\n\t\tdescription,\n\t\tdefaultLimit = RETRIEVAL_DEFAULT_LIMIT,\n\t\tmaxLimit = RETRIEVAL_MAX_LIMIT,\n\t\tscoreThreshold,\n\t\tformatResult = formatScoredResult,\n\t\textendParameters = {},\n\t\tbuildFilter,\n\t} = options\n\n\t// Build tool schema parameters\n\tconst parameters: JSONSchema7 = {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tquery: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'The search query to find relevant documents',\n\t\t\t},\n\t\t\tlimit: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tdescription: `Maximum number of results to return (default: ${defaultLimit}, max: ${maxLimit})`,\n\t\t\t\tminimum: 1,\n\t\t\t\tmaximum: maxLimit,\n\t\t\t\tdefault: defaultLimit,\n\t\t\t},\n\t\t\t...extendParameters,\n\t\t},\n\t\trequired: ['query'],\n\t}\n\n\tconst schema: ToolSchema = {\n\t\tname,\n\t\tdescription,\n\t\tparameters,\n\t}\n\n\tasync function handler(\n\t\targs: Readonly<Record<string, unknown>>,\n\t): Promise<readonly unknown[]> {\n\t\tconst query = args.query\n\t\tif (typeof query !== 'string' || query.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\tconst requestedLimit = args.limit\n\t\tlet limit = defaultLimit\n\t\tif (typeof requestedLimit === 'number' && Number.isInteger(requestedLimit)) {\n\t\t\tlimit = Math.min(Math.max(1, requestedLimit), maxLimit)\n\t\t}\n\n\t\t// Build filter if provided\n\t\tconst filter = buildFilter?.(args)\n\n\t\t// Search vectorstore - only include filter if defined\n\t\tconst searchOptions = filter !== undefined\n\t\t\t? { limit, filter }\n\t\t\t: { limit }\n\t\tconst results = await vectorStore.search(query, searchOptions)\n\n\t\t// Filter by score threshold\n\t\tlet filteredResults = results\n\t\tif (scoreThreshold !== undefined) {\n\t\t\tfilteredResults = results.filter(r => r.score >= scoreThreshold)\n\t\t}\n\n\t\t// Format results\n\t\treturn filteredResults.map(formatResult)\n\t}\n\n\treturn { schema, handler }\n}\n\n// ============================================================================\n// Form Dirty Guard Factory\n// ============================================================================\n\n/**\n * Create a navigation guard that prevents leaving when form is dirty.\n *\n * @param options - Form dirty guard configuration options\n * @returns A navigation guard function\n *\n * @example\n * ```ts\n * import { createForm } from '@mikesaintsg/form'\n * import { createFormDirtyGuard } from '@mikesaintsg/core'\n *\n * const form = createForm({ ... })\n *\n * const guard = createFormDirtyGuard({\n * form,\n * confirmFn: (message) => window.confirm(message),\n * message: 'You have unsaved changes. Continue?',\n * excludePages: ['settings'],\n * })\n *\n * // Use with router\n * router.beforeNavigate(guard)\n * ```\n */\nexport function createFormDirtyGuard<TFormData = unknown, TPage extends string = string>(\n\toptions: FormDirtyGuardOptions<TFormData, TPage>,\n): NavigationGuard<TPage> {\n\tconst {\n\t\tform,\n\t\tconfirmFn,\n\t\tmessage = FORM_DIRTY_DEFAULT_MESSAGE,\n\t\texcludePages = [],\n\t\tonlyFromPages,\n\t} = options\n\n\treturn async function guard(to: TPage, from: TPage): Promise<boolean> {\n\t\t// Check if we should skip guard for this navigation\n\t\tif (shouldSkipFormGuard(to, from, excludePages, onlyFromPages)) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If form is not dirty, allow navigation\n\t\tif (!form.isDirty()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Form is dirty, ask for confirmation\n\t\treturn Promise.resolve(confirmFn(message))\n\t}\n}\n\n// ============================================================================\n// Session Persistence Factory\n// ============================================================================\n\n/**\n * Create a session persistence adapter for storing inference sessions.\n *\n * @param options - Session persistence configuration options\n * @returns A session persistence instance\n *\n * @example\n * ```ts\n * import { createDatabase } from '@mikesaintsg/indexeddb'\n * import { createSessionPersistence } from '@mikesaintsg/core'\n *\n * const db = await createDatabase({ name: 'sessions' })\n * const persistence = createSessionPersistence({\n * database: db,\n * storeName: 'chat_sessions',\n * autoprune: 7 * 24 * 60 * 60 * 1000, // 7 days\n * })\n *\n * // Save session\n * await persistence.save('session-1', session)\n *\n * // Load session\n * const savedSession = await persistence.load('session-1')\n * ```\n */\nexport function createSessionPersistence(\n\toptions: SessionPersistenceOptions,\n): SessionPersistenceInterface {\n\tconst {\n\t\tdatabase,\n\t\tstoreName,\n\t\tautoprune,\n\t\tonSaveError,\n\t} = options\n\n\tconst store = database.store<SerializedSession>(storeName)\n\n\tasync function pruneOldSessions(maxAgeMs: number): Promise<number> {\n\t\tconst now = Date.now()\n\t\tconst cutoff = now - maxAgeMs\n\n\t\tconst allSessions = await store.all()\n\t\tlet prunedCount = 0\n\n\t\tfor (const session of allSessions) {\n\t\t\tif (session.updatedAt < cutoff) {\n\t\t\t\tawait store.remove(session.id)\n\t\t\t\tprunedCount++\n\t\t\t}\n\t\t}\n\n\t\treturn prunedCount\n\t}\n\n\t// Auto-prune on creation if configured\n\tif (autoprune !== undefined && autoprune > 0) {\n\t\tvoid pruneOldSessions(autoprune)\n\t}\n\n\treturn {\n\t\tasync save(id: string, session: SerializableSession): Promise<void> {\n\t\t\ttry {\n\t\t\t\tconst serialized: SerializedSession = {\n\t\t\t\t\tid,\n\t\t\t\t\tmessages: [...session.getMessages()],\n\t\t\t\t\tmetadata: session.getMetadata(),\n\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t}\n\n\t\t\t\tawait store.set(serialized, id)\n\t\t\t} catch (error) {\n\t\t\t\tonSaveError?.(error, id)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\n\t\tasync load(id: string): Promise<SerializedSession | undefined> {\n\t\t\treturn store.get(id)\n\t\t},\n\n\t\tasync delete(id: string): Promise<void> {\n\t\t\tawait store.remove(id)\n\t\t},\n\n\t\tasync list(): Promise<readonly string[]> {\n\t\t\tconst allSessions = await store.all()\n\t\t\treturn allSessions.map(s => s.id)\n\t\t},\n\n\t\tasync prune(maxAgeMs: number): Promise<number> {\n\t\t\treturn pruneOldSessions(maxAgeMs)\n\t\t},\n\t}\n}\n"],"names":["EcosystemError","message","cause","isEcosystemError","error","ok","value","err","isOk","result","isErr","unwrap","defaultValue","unwrapOrThrow","map","fn","mapErr","chain","computeContentHash","text","data","hashBuffer","b","isToolCall","shouldSkipFormGuard","to","from","excludePages","onlyFromPages","formatScoredResult","BRIDGE_DEFAULT_TIMEOUT","RETRIEVAL_DEFAULT_LIMIT","RETRIEVAL_MAX_LIMIT","FORM_DIRTY_DEFAULT_MESSAGE","createToolCallBridge","options","registry","timeout","onError","onBeforeExecute","onAfterExecute","executeWithTimeout","toolCall","timeoutPromise","_","reject","errorMessage","toolCallOrCalls","tc","name","createRetrievalTool","vectorStore","description","defaultLimit","maxLimit","scoreThreshold","formatResult","extendParameters","buildFilter","parameters","schema","handler","args","query","requestedLimit","limit","filter","searchOptions","results","filteredResults","r","createFormDirtyGuard","form","confirmFn","createSessionPersistence","database","storeName","autoprune","onSaveError","store","pruneOldSessions","maxAgeMs","cutoff","allSessions","prunedCount","session","id","serialized","s"],"mappings":"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"}
|