@peerigon/typescript-toolkit 2.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,7 +46,7 @@ import { assert } from "@peerigon/typescript-toolkit/assert";
46
46
  | [`enums`](./src/enums/README.md) | Lightweight string-enum alternative for `erasableSyntaxOnly` TypeScript projects | [→](./src/enums/README.md) |
47
47
  | [`match`](./src/match/README.md) | Exhaustive pattern matching with compile-time case checks, similar to `switch` | [→](./src/match/README.md) |
48
48
  | [`result`](./src/result/README.md) | Type-safe error handling with pending, success, and error states | [→](./src/result/README.md) |
49
- | [`signals`](./src/signals/README.md) | Push-based reactive state with explicit subscribers and `signal.from` adapters | [→](./src/signals/README.md) |
49
+ | [`signals`](./src/signals/README.md) | Push-based reactive state with explicit watchers and `signal.from` adapters | [→](./src/signals/README.md) |
50
50
  | [`unwrap`](./src/unwrap/README.md) | Extract values from `Result` or nullable types, with optional fallback support | [→](./src/unwrap/README.md) |
51
51
 
52
52
  ## License
@@ -94,19 +94,20 @@ declare const pending: <const Data = undefined>({ data, createdAt, }?: Pick<Part
94
94
  /**
95
95
  * Creates a result in the success state.
96
96
  *
97
- * @param options.data - The data to store in the result
97
+ * @param data - The data to store in the result
98
98
  * @param options.createdAt - The date when the result was created
99
99
  * @returns The successful result
100
100
  */
101
- declare const success: <const Data>({ data, createdAt, }: Pick<Result.Success<Data>, "data"> & Partial<ResultMetadata>) => Result.Success<Data>;
101
+ declare const success: <const Data>(data: Data, { createdAt }?: Partial<ResultMetadata>) => Result.Success<Data>;
102
102
  /**
103
103
  * Creates a result in the error state.
104
104
  *
105
- * @param options.error - The error to store in the result
105
+ * @param givenError - The error to store in the result
106
106
  * @param options.data - Potentially stale data from a previous result
107
+ * @param options.createdAt - The date when the result was created
107
108
  * @returns The failed result
108
109
  */
109
- declare const error: <const GivenError extends Error, const Data = never>({ error: givenError, data, createdAt, }: Pick<Result.Error<GivenError, Data>, "error"> & Pick<Partial<Result.Error<GivenError, Data>>, "data"> & Partial<ResultMetadata>) => Result.Error<GivenError, Data>;
110
+ declare const error: <const GivenError extends Error, const Data = never>(givenError: GivenError, { data, createdAt, }?: Pick<Partial<Result.Error<GivenError, Data>>, "data"> & Partial<ResultMetadata>) => Result.Error<GivenError, Data>;
110
111
  /**
111
112
  * Calls the function and returns it as result.
112
113
  * If the function throws an Error, an error result is returned.
@@ -1 +1 @@
1
- {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/result/result.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/result/result.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ // We're using manual prototype inheritance here, so `this` outside of a class is expected.
2
+ /* eslint-disable unicorn/no-this-outside-of-class */
1
3
  import { createPrototype } from "../lib/create-prototype.js";
2
4
  import { stringify } from "../lib/string.js";
3
5
  import { symbolOfResult } from "./result.lib.js";
@@ -46,11 +48,11 @@ const pendingPrototype = createPrototype({
46
48
  /**
47
49
  * Creates a result in the success state.
48
50
  *
49
- * @param options.data - The data to store in the result
51
+ * @param data - The data to store in the result
50
52
  * @param options.createdAt - The date when the result was created
51
53
  * @returns The successful result
52
54
  */
53
- const success = ({ data, createdAt = new Date(), }) => {
55
+ const success = (data, { createdAt = new Date() } = {}) => {
54
56
  const successResult = Object.create(successPrototype, {
55
57
  data: { value: data, enumerable: true },
56
58
  });
@@ -72,11 +74,12 @@ const successPrototype = createPrototype({
72
74
  /**
73
75
  * Creates a result in the error state.
74
76
  *
75
- * @param options.error - The error to store in the result
77
+ * @param givenError - The error to store in the result
76
78
  * @param options.data - Potentially stale data from a previous result
79
+ * @param options.createdAt - The date when the result was created
77
80
  * @returns The failed result
78
81
  */
79
- const error = ({ error: givenError, data, createdAt = new Date(), }) => {
82
+ const error = (givenError, { data, createdAt = new Date(), } = {}) => {
80
83
  const errorResult = Object.create(errorPrototype, {
81
84
  data: { value: data, enumerable: true },
82
85
  error: { value: givenError, enumerable: true },
@@ -106,11 +109,11 @@ const errorPrototype = createPrototype({
106
109
  */
107
110
  const from = (fn) => {
108
111
  try {
109
- return success({ data: fn() });
112
+ return success(fn());
110
113
  }
111
114
  catch (caughtError) {
112
115
  if (isError(caughtError)) {
113
- return error({ error: caughtError });
116
+ return error(caughtError);
114
117
  }
115
118
  throw caughtError;
116
119
  }
@@ -125,11 +128,11 @@ const from = (fn) => {
125
128
  */
126
129
  const fromAsync = async (fn) => {
127
130
  try {
128
- return success({ data: await fn() });
131
+ return success(await fn());
129
132
  }
130
133
  catch (caughtError) {
131
134
  if (isError(caughtError)) {
132
- return error({ error: caughtError });
135
+ return error(caughtError);
133
136
  }
134
137
  throw caughtError;
135
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/result/result.ts"],"names":[],"mappings":"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","sourcesContent":["import { createPrototype } from \"../lib/create-prototype.ts\";\nimport { stringify } from \"../lib/string.ts\";\nimport { symbolOfResult } from \"./result.lib.ts\";\n\n// Namespaces are only used to group related types together.\n/* eslint-disable @typescript-eslint/no-namespace */\n\n// This module uses prototypes to create objects for the Result.Pending, Result.Success and Result.Error types.\n// This way unimportant properties won't show up in the debugger and we keep the memory footprint low.\n\n/**\n * Represents some async data that could be in the following states:\n *\n * - initial (not implemented, see below)\n * - pending\n * - success\n * - error\n *\n * This type is inspired by https://rametta.org/posts/elm-remote-data/ and has been\n * designed to be aligned with tanstack query's useQuery() result.\n * For instance, it can be used by a React component that wants to handle asynchronous\n * data but does not want to call useQuery directly.\n *\n * The initial state has not been implemented because it's not compatible\n * with tanstack query. If the initial state is needed,\n * it can be represented as Result | undefined\n */\nexport type Result<\n Data = unknown,\n GivenError extends GenericError = GenericError,\n> =\n | Result.Pending<Data | undefined>\n | Result.Success<Data>\n | Result.Error<GivenError, Data | undefined>;\n\nexport const Result = {\n Status: {\n Pending: \"pending\",\n Success: \"success\",\n Error: \"error\",\n },\n} as const;\n\nexport namespace Result {\n export namespace Status {\n export type Pending = typeof Result.Status.Pending;\n export type Success = typeof Result.Status.Success;\n export type Error = typeof Result.Status.Error;\n }\n\n export type Status = Status.Pending | Status.Success | Status.Error;\n\n /**\n * Represents a pending result where data is being loaded.\n * Pending might have stale data, but there's new data inflight.\n */\n export type Pending<Data = undefined> = Readonly<{\n status: Status.Pending;\n /** Is true when there's data */\n isSuccess: false;\n /** Is true when there's an error */\n isError: false;\n /** Is true when there's no result yet */\n isPending: true;\n /** Potentially stale data from a previous result */\n data: Data;\n error: null;\n }>;\n\n /**\n * Represents a successful result that holds some data.\n */\n export type Success<Data = unknown> = Readonly<{\n status: Status.Success;\n /** Is true when there's data */\n isSuccess: true;\n /** Is true when there's an error */\n isError: false;\n /** Is true when there's no result yet */\n isPending: false;\n data: Data;\n error: null;\n }>;\n\n /**\n * Represents a failed result that holds an error.\n * Might also contain stale data from a previous result.\n */\n export type Error<\n GivenError extends GenericError = GenericError,\n Data = undefined,\n > = Readonly<{\n status: Status.Error;\n /** Is true when there's data */\n isSuccess: false;\n /** Is true when there's an error */\n isError: true;\n /** Is true when there's no result yet */\n isPending: false;\n /** Potentially stale data from a previous result */\n data: Data;\n /** The error that occurred */\n error: GivenError;\n }>;\n\n /**\n * Represents a synchronous result that can be either success or error (no pending state).\n */\n export type Sync<\n Data = unknown,\n GivenError extends GenericError = GenericError,\n > = Success<Data> | Error<GivenError, Data>;\n}\n\nconst setMetadata = <Data>(result: Result<Data>, metadata: ResultMetadata) => {\n Object.defineProperty(result, symbolOfResult, {\n value: metadata,\n enumerable: false,\n });\n};\n\nconst getMetadata = <Data>(result: Result<Data>): ResultMetadata => {\n return (result as { [symbolOfResult]?: ResultMetadata })[symbolOfResult]!;\n};\n\n/**\n * Creates a result in the pending state.\n *\n * @param options.data - Potentially stale data from a previous result\n * @param options.createdAt - The date when the result was created\n * @returns The pending result\n */\nconst pending = <const Data = undefined>({\n data,\n createdAt = new Date(),\n}: Pick<Partial<Result.Pending<Data>>, \"data\"> &\n Partial<ResultMetadata> = {}): Result.Pending<Data> => {\n const pendingResult: Result.Pending<Data> = Object.create(pendingPrototype, {\n data: { value: data, enumerable: true },\n });\n\n setMetadata(pendingResult, { createdAt });\n\n return pendingResult;\n};\n\nconst pendingPrototype: Result.Pending = createPrototype(\n {\n status: Result.Status.Pending,\n isSuccess: false,\n isError: false,\n isPending: true,\n data: undefined,\n error: null,\n } as const,\n {\n toString(this: Result.Pending<unknown>) {\n return `Result.Pending(${\n this.data === undefined ? \"\" : stringify(this.data)\n })`;\n },\n },\n);\n\n/**\n * Creates a result in the success state.\n *\n * @param options.data - The data to store in the result\n * @param options.createdAt - The date when the result was created\n * @returns The successful result\n */\nconst success = <const Data>({\n data,\n createdAt = new Date(),\n}: Pick<Result.Success<Data>, \"data\"> &\n Partial<ResultMetadata>): Result.Success<Data> => {\n const successResult: Result.Success<Data> = Object.create(successPrototype, {\n data: { value: data, enumerable: true },\n });\n\n setMetadata(successResult, { createdAt });\n\n return successResult;\n};\n\nconst successPrototype: Result.Success<undefined> = createPrototype(\n {\n status: Result.Status.Success,\n isSuccess: true,\n isError: false,\n isPending: false,\n data: undefined,\n error: null,\n } as const,\n {\n toString(this: Result.Success) {\n return `Result.Success(${stringify(this.data)})`;\n },\n },\n);\n\n/**\n * Creates a result in the error state.\n *\n * @param options.error - The error to store in the result\n * @param options.data - Potentially stale data from a previous result\n * @returns The failed result\n */\nconst error = <const GivenError extends Error, const Data = never>({\n error: givenError,\n data,\n createdAt = new Date(),\n}: Pick<Result.Error<GivenError, Data>, \"error\"> &\n Pick<Partial<Result.Error<GivenError, Data>>, \"data\"> &\n Partial<ResultMetadata>): Result.Error<GivenError, Data> => {\n const errorResult: Result.Error<GivenError, Data> = Object.create(\n errorPrototype,\n {\n data: { value: data, enumerable: true },\n error: { value: givenError, enumerable: true },\n },\n );\n\n setMetadata(errorResult, { createdAt });\n\n return errorResult;\n};\n\nconst errorPrototype: Result.Error = createPrototype(\n {\n status: Result.Status.Error,\n isSuccess: false,\n isError: true,\n isPending: false,\n data: undefined,\n error: new Error(\"Default error\"),\n } as const,\n {\n toString(this: Result.Error) {\n return `Result.Error(${stringify(this.error.message)})`;\n },\n },\n);\n\n/**\n * Calls the function and returns it as result.\n * If the function throws an Error, an error result is returned.\n * If the function throws anything else, it is rethrown.\n *\n * @param fn - The function to call\n * @returns The result of the function\n */\nconst from = <Data>(fn: () => Data): Result.Sync<Data> => {\n try {\n return success({ data: fn() });\n } catch (caughtError) {\n if (isError(caughtError)) {\n return error<GenericError>({ error: caughtError });\n }\n\n throw caughtError;\n }\n};\n\n/**\n * Calls and awaits the async function and returns it as result.\n * If the function rejects the promise, an error result is returned.\n * If the function rejects with anything else, the rejection is rethrown.\n *\n * @param fn - The async function to call and await\n * @returns The result of the async function\n */\nconst fromAsync = async <Data>(\n fn: () => Promise<Data>,\n): Promise<Result.Sync<Data>> => {\n try {\n return success({ data: await fn() });\n } catch (caughtError) {\n if (isError(caughtError)) {\n return error<GenericError>({ error: caughtError });\n }\n\n throw caughtError;\n }\n};\n\n/**\n * Checks if the given value is an Error. Doesn't use instanceof so that\n * DOMException and errors from a different realm can be checked as well.\n */\nconst isError = (error: unknown): error is GenericError => {\n if (\"isError\" in Error && typeof Error.isError === \"function\") {\n const result: unknown = Error.isError(error);\n\n if (typeof result === \"boolean\") {\n return result;\n }\n }\n\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n typeof error.name === \"string\" &&\n \"message\" in error &&\n typeof error.message === \"string\" &&\n \"stack\" in error &&\n typeof error.stack === \"string\"\n );\n};\n\ntype CaseHandlers<\n GivenResult extends Result | null | undefined,\n ReturnType = unknown,\n> = {\n pending?:\n | ((\n maybeData: Extract<\n GivenResult,\n { status: Result.Status.Pending }\n >[\"data\"],\n ) => ReturnType)\n | ReturnType;\n success?:\n | ((\n data: Extract<GivenResult, { status: Result.Status.Success }>[\"data\"],\n ) => ReturnType)\n | ReturnType;\n error?:\n | ((\n error: Extract<GivenResult, { status: Result.Status.Error }>[\"error\"],\n ) => ReturnType)\n | ReturnType;\n else: ((result: GivenResult) => ReturnType) | ReturnType;\n};\n\ntype ResultWrapper<GivenResult extends Result | null | undefined> = {\n case: <ReturnType>(\n handlers: CaseHandlers<GivenResult, ReturnType>,\n ) => ReturnType;\n};\n\ntype ResultFn = {\n <GivenResult extends Result | null | undefined>(\n givenResult: GivenResult,\n ): ResultWrapper<GivenResult>;\n from: typeof from;\n fromAsync: typeof fromAsync;\n pending: typeof pending;\n success: typeof success;\n error: typeof error;\n metadata: typeof getMetadata;\n};\n\nexport const result: ResultFn = Object.assign(\n <GivenResult extends Result | null | undefined>(\n givenResult: GivenResult,\n ): ResultWrapper<GivenResult> => {\n return {\n case: <ReturnType>(\n handlers: CaseHandlers<GivenResult, ReturnType>,\n ): ReturnType => {\n if (\n givenResult?.status === Result.Status.Pending &&\n \"pending\" in handlers\n ) {\n return typeof handlers.pending === \"function\"\n ? (\n handlers.pending as Extract<\n typeof handlers.pending,\n (maybeData: unknown) => ReturnType\n >\n )(givenResult.data)\n : (handlers.pending as ReturnType);\n }\n if (\n givenResult?.status === Result.Status.Success &&\n \"success\" in handlers\n ) {\n return typeof handlers.success === \"function\"\n ? (\n handlers.success as Extract<\n typeof handlers.success,\n (data: unknown) => ReturnType\n >\n )(givenResult.data)\n : (handlers.success as ReturnType);\n }\n if (\n givenResult?.status === Result.Status.Error &&\n \"error\" in handlers\n ) {\n return typeof handlers.error === \"function\"\n ? (\n handlers.error as Extract<\n typeof handlers.error,\n (error: unknown) => ReturnType\n >\n )(givenResult.error)\n : (handlers.error as ReturnType);\n }\n return typeof handlers.else === \"function\"\n ? (\n handlers.else as Extract<\n typeof handlers.else,\n (result: unknown) => ReturnType\n >\n )(givenResult)\n : handlers.else;\n },\n };\n },\n {\n from,\n fromAsync,\n pending,\n success,\n error,\n metadata: getMetadata,\n },\n);\n\nexport { isResult } from \"./result.lib.ts\";\n\ntype GenericError = Error;\n\ntype ResultMetadata = {\n /** The date when the result was created */\n createdAt: Date;\n};\n"]}
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/result/result.ts"],"names":[],"mappings":"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","sourcesContent":["// We're using manual prototype inheritance here, so `this` outside of a class is expected.\n/* eslint-disable unicorn/no-this-outside-of-class */\nimport { createPrototype } from \"../lib/create-prototype.ts\";\nimport { stringify } from \"../lib/string.ts\";\nimport { symbolOfResult } from \"./result.lib.ts\";\n\n// Namespaces are only used to group related types together.\n/* eslint-disable @typescript-eslint/no-namespace */\n\n// This module uses prototypes to create objects for the Result.Pending, Result.Success and Result.Error types.\n// This way unimportant properties won't show up in the debugger and we keep the memory footprint low.\n\n/**\n * Represents some async data that could be in the following states:\n *\n * - initial (not implemented, see below)\n * - pending\n * - success\n * - error\n *\n * This type is inspired by https://rametta.org/posts/elm-remote-data/ and has been\n * designed to be aligned with tanstack query's useQuery() result.\n * For instance, it can be used by a React component that wants to handle asynchronous\n * data but does not want to call useQuery directly.\n *\n * The initial state has not been implemented because it's not compatible\n * with tanstack query. If the initial state is needed,\n * it can be represented as Result | undefined\n */\nexport type Result<\n Data = unknown,\n GivenError extends GenericError = GenericError,\n> =\n | Result.Pending<Data | undefined>\n | Result.Success<Data>\n | Result.Error<GivenError, Data | undefined>;\n\nexport const Result = {\n Status: {\n Pending: \"pending\",\n Success: \"success\",\n Error: \"error\",\n },\n} as const;\n\nexport namespace Result {\n export namespace Status {\n export type Pending = typeof Result.Status.Pending;\n export type Success = typeof Result.Status.Success;\n export type Error = typeof Result.Status.Error;\n }\n\n export type Status = Status.Pending | Status.Success | Status.Error;\n\n /**\n * Represents a pending result where data is being loaded.\n * Pending might have stale data, but there's new data inflight.\n */\n export type Pending<Data = undefined> = Readonly<{\n status: Status.Pending;\n /** Is true when there's data */\n isSuccess: false;\n /** Is true when there's an error */\n isError: false;\n /** Is true when there's no result yet */\n isPending: true;\n /** Potentially stale data from a previous result */\n data: Data;\n error: null;\n }>;\n\n /**\n * Represents a successful result that holds some data.\n */\n export type Success<Data = unknown> = Readonly<{\n status: Status.Success;\n /** Is true when there's data */\n isSuccess: true;\n /** Is true when there's an error */\n isError: false;\n /** Is true when there's no result yet */\n isPending: false;\n data: Data;\n error: null;\n }>;\n\n /**\n * Represents a failed result that holds an error.\n * Might also contain stale data from a previous result.\n */\n export type Error<\n GivenError extends GenericError = GenericError,\n Data = undefined,\n > = Readonly<{\n status: Status.Error;\n /** Is true when there's data */\n isSuccess: false;\n /** Is true when there's an error */\n isError: true;\n /** Is true when there's no result yet */\n isPending: false;\n /** Potentially stale data from a previous result */\n data: Data;\n /** The error that occurred */\n error: GivenError;\n }>;\n\n /**\n * Represents a synchronous result that can be either success or error (no pending state).\n */\n export type Sync<\n Data = unknown,\n GivenError extends GenericError = GenericError,\n > = Success<Data> | Error<GivenError, Data>;\n}\n\nconst setMetadata = <Data>(result: Result<Data>, metadata: ResultMetadata) => {\n Object.defineProperty(result, symbolOfResult, {\n value: metadata,\n enumerable: false,\n });\n};\n\nconst getMetadata = <Data>(result: Result<Data>): ResultMetadata => {\n return (result as { [symbolOfResult]?: ResultMetadata })[symbolOfResult]!;\n};\n\n/**\n * Creates a result in the pending state.\n *\n * @param options.data - Potentially stale data from a previous result\n * @param options.createdAt - The date when the result was created\n * @returns The pending result\n */\nconst pending = <const Data = undefined>({\n data,\n createdAt = new Date(),\n}: Pick<Partial<Result.Pending<Data>>, \"data\"> &\n Partial<ResultMetadata> = {}): Result.Pending<Data> => {\n const pendingResult: Result.Pending<Data> = Object.create(pendingPrototype, {\n data: { value: data, enumerable: true },\n });\n\n setMetadata(pendingResult, { createdAt });\n\n return pendingResult;\n};\n\nconst pendingPrototype: Result.Pending = createPrototype(\n {\n status: Result.Status.Pending,\n isSuccess: false,\n isError: false,\n isPending: true,\n data: undefined,\n error: null,\n } as const,\n {\n toString(this: Result.Pending<unknown>) {\n return `Result.Pending(${\n this.data === undefined ? \"\" : stringify(this.data)\n })`;\n },\n },\n);\n\n/**\n * Creates a result in the success state.\n *\n * @param data - The data to store in the result\n * @param options.createdAt - The date when the result was created\n * @returns The successful result\n */\nconst success = <const Data>(\n data: Data,\n { createdAt = new Date() }: Partial<ResultMetadata> = {},\n): Result.Success<Data> => {\n const successResult: Result.Success<Data> = Object.create(successPrototype, {\n data: { value: data, enumerable: true },\n });\n\n setMetadata(successResult, { createdAt });\n\n return successResult;\n};\n\nconst successPrototype: Result.Success<undefined> = createPrototype(\n {\n status: Result.Status.Success,\n isSuccess: true,\n isError: false,\n isPending: false,\n data: undefined,\n error: null,\n } as const,\n {\n toString(this: Result.Success) {\n return `Result.Success(${stringify(this.data)})`;\n },\n },\n);\n\n/**\n * Creates a result in the error state.\n *\n * @param givenError - The error to store in the result\n * @param options.data - Potentially stale data from a previous result\n * @param options.createdAt - The date when the result was created\n * @returns The failed result\n */\nconst error = <const GivenError extends Error, const Data = never>(\n givenError: GivenError,\n {\n data,\n createdAt = new Date(),\n }: Pick<Partial<Result.Error<GivenError, Data>>, \"data\"> &\n Partial<ResultMetadata> = {},\n): Result.Error<GivenError, Data> => {\n const errorResult: Result.Error<GivenError, Data> = Object.create(\n errorPrototype,\n {\n data: { value: data, enumerable: true },\n error: { value: givenError, enumerable: true },\n },\n );\n\n setMetadata(errorResult, { createdAt });\n\n return errorResult;\n};\n\nconst errorPrototype: Result.Error = createPrototype(\n {\n status: Result.Status.Error,\n isSuccess: false,\n isError: true,\n isPending: false,\n data: undefined,\n error: new Error(\"Default error\"),\n } as const,\n {\n toString(this: Result.Error) {\n return `Result.Error(${stringify(this.error.message)})`;\n },\n },\n);\n\n/**\n * Calls the function and returns it as result.\n * If the function throws an Error, an error result is returned.\n * If the function throws anything else, it is rethrown.\n *\n * @param fn - The function to call\n * @returns The result of the function\n */\nconst from = <Data>(fn: () => Data): Result.Sync<Data> => {\n try {\n return success(fn());\n } catch (caughtError) {\n if (isError(caughtError)) {\n return error<GenericError>(caughtError);\n }\n\n throw caughtError;\n }\n};\n\n/**\n * Calls and awaits the async function and returns it as result.\n * If the function rejects the promise, an error result is returned.\n * If the function rejects with anything else, the rejection is rethrown.\n *\n * @param fn - The async function to call and await\n * @returns The result of the async function\n */\nconst fromAsync = async <Data>(\n fn: () => Promise<Data>,\n): Promise<Result.Sync<Data>> => {\n try {\n return success(await fn());\n } catch (caughtError) {\n if (isError(caughtError)) {\n return error<GenericError>(caughtError);\n }\n\n throw caughtError;\n }\n};\n\n/**\n * Checks if the given value is an Error. Doesn't use instanceof so that\n * DOMException and errors from a different realm can be checked as well.\n */\nconst isError = (error: unknown): error is GenericError => {\n if (\"isError\" in Error && typeof Error.isError === \"function\") {\n const result: unknown = Error.isError(error);\n\n if (typeof result === \"boolean\") {\n return result;\n }\n }\n\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"name\" in error &&\n typeof error.name === \"string\" &&\n \"message\" in error &&\n typeof error.message === \"string\" &&\n \"stack\" in error &&\n typeof error.stack === \"string\"\n );\n};\n\ntype CaseHandlers<\n GivenResult extends Result | null | undefined,\n ReturnType = unknown,\n> = {\n pending?:\n | ((\n maybeData: Extract<\n GivenResult,\n { status: Result.Status.Pending }\n >[\"data\"],\n ) => ReturnType)\n | ReturnType;\n success?:\n | ((\n data: Extract<GivenResult, { status: Result.Status.Success }>[\"data\"],\n ) => ReturnType)\n | ReturnType;\n error?:\n | ((\n error: Extract<GivenResult, { status: Result.Status.Error }>[\"error\"],\n ) => ReturnType)\n | ReturnType;\n else: ((result: GivenResult) => ReturnType) | ReturnType;\n};\n\ntype ResultWrapper<GivenResult extends Result | null | undefined> = {\n case: <ReturnType>(\n handlers: CaseHandlers<GivenResult, ReturnType>,\n ) => ReturnType;\n};\n\ntype ResultFn = {\n <GivenResult extends Result | null | undefined>(\n givenResult: GivenResult,\n ): ResultWrapper<GivenResult>;\n from: typeof from;\n fromAsync: typeof fromAsync;\n pending: typeof pending;\n success: typeof success;\n error: typeof error;\n metadata: typeof getMetadata;\n};\n\nexport const result: ResultFn = Object.assign(\n <GivenResult extends Result | null | undefined>(\n givenResult: GivenResult,\n ): ResultWrapper<GivenResult> => {\n return {\n case: <ReturnType>(\n handlers: CaseHandlers<GivenResult, ReturnType>,\n ): ReturnType => {\n if (\n givenResult?.status === Result.Status.Pending &&\n \"pending\" in handlers\n ) {\n return typeof handlers.pending === \"function\"\n ? (\n handlers.pending as Extract<\n typeof handlers.pending,\n (maybeData: unknown) => ReturnType\n >\n )(givenResult.data)\n : (handlers.pending as ReturnType);\n }\n if (\n givenResult?.status === Result.Status.Success &&\n \"success\" in handlers\n ) {\n return typeof handlers.success === \"function\"\n ? (\n handlers.success as Extract<\n typeof handlers.success,\n (data: unknown) => ReturnType\n >\n )(givenResult.data)\n : (handlers.success as ReturnType);\n }\n if (\n givenResult?.status === Result.Status.Error &&\n \"error\" in handlers\n ) {\n return typeof handlers.error === \"function\"\n ? (\n handlers.error as Extract<\n typeof handlers.error,\n (error: unknown) => ReturnType\n >\n )(givenResult.error)\n : (handlers.error as ReturnType);\n }\n return typeof handlers.else === \"function\"\n ? (\n handlers.else as Extract<\n typeof handlers.else,\n (result: unknown) => ReturnType\n >\n )(givenResult)\n : handlers.else;\n },\n };\n },\n {\n from,\n fromAsync,\n pending,\n success,\n error,\n metadata: getMetadata,\n },\n);\n\nexport { isResult } from \"./result.lib.ts\";\n\ntype GenericError = Error;\n\ntype ResultMetadata = {\n /** The date when the result was created */\n createdAt: Date;\n};\n"]}
@@ -1,19 +1,21 @@
1
- export type ReadSignal<Value> = {
1
+ export declare const signal: {
2
+ <Value>(initialValue: Value): Signal<Value>;
3
+ from<Value>(getFromSource: () => Value, subscribeToSource: (notify: () => void) => () => void): Omit<Signal<Value>, "set">;
4
+ };
5
+ export type SignalGetter<Value> = {
2
6
  (): Value;
3
- subscribe: (reader: SignalReader<Value>) => () => void;
7
+ watch: (watcher: SignalWatcher<Value>) => SignalUnwatch;
4
8
  };
5
- export type WriteSignal<Value> = (value: Value) => void;
6
- export type Signal<Value> = Disposable & {
7
- read: ReadSignal<Value>;
8
- write: WriteSignal<Value>;
9
- subscribe: ReadSignal<Value>["subscribe"];
9
+ export type SignalWatcher<Value> = (update: SignalUpdate<Value>) => void;
10
+ export type SignalUpdate<Value> = {
11
+ new: Value;
12
+ old: Value;
10
13
  };
11
- export declare const signal: {
12
- <Value>(initialValue: Value): Signal<Value>;
13
- from<Value>(readFromSource: () => Value, subscribeToSource: (notify: () => void) => () => void): Omit<Signal<Value>, "write">;
14
+ export type SignalSetter<Value> = (value: Value) => void;
15
+ export type SignalUnwatch = (() => void) & Disposable;
16
+ export type Signal<Value> = Disposable & {
17
+ get: SignalGetter<Value>;
18
+ set: SignalSetter<Value>;
19
+ watch: SignalGetter<Value>["watch"];
14
20
  };
15
- export type SignalReader<Value> = ({ value, previousValue, }: {
16
- value: Value;
17
- previousValue: Value;
18
- }) => void;
19
21
  //# sourceMappingURL=signals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals/signals.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,KAAK,IAAI;IAC9B,IAAI,KAAK,CAAC;IACV,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,KAAK,MAAM,IAAI,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAExD,MAAM,MAAM,MAAM,CAAC,KAAK,IAAI,UAAU,GAAG;IACvC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,MAAM;KAAI,KAAK,gBAAgB,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;SA6BlD,KAAK,kBACF,MAAM,KAAK,qBACR,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,GACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAL9B,CAAC;AAoCF,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI,CAAC,EACjC,KAAK,EACL,aAAa,GACd,EAAE;IACD,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,KAAK,CAAC;CACtB,KAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals/signals.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;KAAI,KAAK,gBAAgB,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;SAiClD,KAAK,iBACH,MAAM,KAAK,qBACP,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,GACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CAL5B,CAAC;AAyDF,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI;IAChC,IAAI,KAAK,CAAC;IACV,KAAK,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI;IAChC,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,KAAK,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEzD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC;AAEtD,MAAM,MAAM,MAAM,CAAC,KAAK,IAAI,UAAU,GAAG;IACvC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACzB,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACzB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;CACrC,CAAC"}
@@ -1,51 +1,74 @@
1
1
  export const signal = (initialValue) => {
2
- const readers = new Set();
2
+ const watchers = new Set();
3
3
  let value = initialValue;
4
- const subscribe = (reader) => {
5
- readers.add(reader);
6
- return () => {
7
- readers.delete(reader);
8
- };
4
+ const watch = (watcher) => {
5
+ watchers.add(watcher);
6
+ return createUnwatch(() => {
7
+ watchers.delete(watcher);
8
+ });
9
9
  };
10
- const read = () => value;
11
- read.subscribe = subscribe;
12
- const write = (newValue) => {
13
- const previousValue = value;
10
+ const get = () => value;
11
+ get.watch = watch;
12
+ const set = (newValue) => {
13
+ const oldValue = value;
14
14
  value = newValue;
15
- for (const reader of readers) {
16
- reader({ value, previousValue });
15
+ const update = {
16
+ new: newValue,
17
+ old: oldValue,
18
+ };
19
+ for (const watcher of watchers) {
20
+ watcher(update);
17
21
  }
18
22
  };
19
23
  const dispose = () => {
20
- readers.clear();
24
+ watchers.clear();
21
25
  };
22
- return { read, write, subscribe, [Symbol.dispose]: dispose };
26
+ return { get, set, watch, [Symbol.dispose]: dispose };
23
27
  };
24
- signal.from = (readFromSource, subscribeToSource) => {
25
- const derivedSignal = signal(readFromSource());
26
- let readerCount = 0;
27
- let unsubscribeFromSource;
28
- const subscribe = (reader) => {
29
- const unsubscribe = derivedSignal.subscribe(reader);
30
- if (readerCount === 0) {
31
- unsubscribeFromSource = subscribeToSource(() => {
32
- derivedSignal.write(readFromSource());
28
+ signal.from = (getFromSource, subscribeToSource) => {
29
+ const derivedSignal = signal(getFromSource());
30
+ let watcherCount = 0;
31
+ let unwatchFromSource;
32
+ let disposed = false;
33
+ const watch = (watcher) => {
34
+ const unwatch = derivedSignal.watch(watcher);
35
+ if (watcherCount === 0) {
36
+ unwatchFromSource = subscribeToSource(() => {
37
+ derivedSignal.set(getFromSource());
33
38
  });
34
39
  }
35
- readerCount++;
36
- return () => {
37
- unsubscribe();
38
- readerCount--;
39
- if (readerCount === 0) {
40
- unsubscribeFromSource?.();
41
- unsubscribeFromSource = undefined;
40
+ watcherCount++;
41
+ return createUnwatch(() => {
42
+ if (disposed) {
43
+ return;
42
44
  }
43
- };
45
+ unwatch();
46
+ watcherCount--;
47
+ if (watcherCount === 0) {
48
+ unwatchFromSource?.();
49
+ unwatchFromSource = undefined;
50
+ }
51
+ });
44
52
  };
53
+ const get = () => derivedSignal.get();
54
+ get.watch = watch;
45
55
  const dispose = () => {
46
- unsubscribeFromSource?.();
56
+ if (disposed) {
57
+ return;
58
+ }
59
+ disposed = true;
60
+ unwatchFromSource?.();
61
+ unwatchFromSource = undefined;
62
+ watcherCount = 0;
47
63
  derivedSignal[Symbol.dispose]();
48
64
  };
49
- return { read: derivedSignal.read, subscribe, [Symbol.dispose]: dispose };
65
+ return { get, watch, [Symbol.dispose]: dispose };
66
+ };
67
+ const createUnwatch = (remove) => {
68
+ const unwatch = () => {
69
+ remove();
70
+ };
71
+ unwatch[Symbol.dispose] = unwatch;
72
+ return unwatch;
50
73
  };
51
74
  //# sourceMappingURL=signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals/signals.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,MAAM,GAAG,CAAQ,YAAmB,EAAiB,EAAE;IAClE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,IAAI,KAAK,GAAG,YAAY,CAAC;IAEzB,MAAM,SAAS,GAAmC,CAAC,MAAM,EAAE,EAAE;QAC3D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,IAAI,GAAsB,GAAG,EAAE,CAAC,KAAK,CAAC;IAC5C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAE3B,MAAM,KAAK,GAAuB,CAAC,QAAQ,EAAE,EAAE;QAC7C,MAAM,aAAa,GAAG,KAAK,CAAC;QAC5B,KAAK,GAAG,QAAQ,CAAC;QACjB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,IAAI,GAAG,CACZ,cAA2B,EAC3B,iBAAqD,EACvB,EAAE;IAChC,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAE/C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,qBAA+C,CAAC;IACpD,MAAM,SAAS,GAAG,CAAC,MAA2B,EAAE,EAAE;QAChD,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,qBAAqB,GAAG,iBAAiB,CAAC,GAAG,EAAE;gBAC7C,aAAa,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC;QACD,WAAW,EAAE,CAAC;QACd,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;gBACtB,qBAAqB,EAAE,EAAE,CAAC;gBAC1B,qBAAqB,GAAG,SAAS,CAAC;YACpC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,qBAAqB,EAAE,EAAE,CAAC;QAC1B,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IAClC,CAAC,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;AAC5E,CAAC,CAAC","sourcesContent":["export type ReadSignal<Value> = {\n (): Value;\n subscribe: (reader: SignalReader<Value>) => () => void;\n};\n\nexport type WriteSignal<Value> = (value: Value) => void;\n\nexport type Signal<Value> = Disposable & {\n read: ReadSignal<Value>;\n write: WriteSignal<Value>;\n subscribe: ReadSignal<Value>[\"subscribe\"];\n};\n\nexport const signal = <Value>(initialValue: Value): Signal<Value> => {\n const readers = new Set<SignalReader<Value>>();\n let value = initialValue;\n\n const subscribe: ReadSignal<Value>[\"subscribe\"] = (reader) => {\n readers.add(reader);\n return () => {\n readers.delete(reader);\n };\n };\n\n const read: ReadSignal<Value> = () => value;\n read.subscribe = subscribe;\n\n const write: WriteSignal<Value> = (newValue) => {\n const previousValue = value;\n value = newValue;\n for (const reader of readers) {\n reader({ value, previousValue });\n }\n };\n\n const dispose = () => {\n readers.clear();\n };\n\n return { read, write, subscribe, [Symbol.dispose]: dispose };\n};\n\nsignal.from = <Value>(\n readFromSource: () => Value,\n subscribeToSource: (notify: () => void) => () => void,\n): Omit<Signal<Value>, \"write\"> => {\n const derivedSignal = signal(readFromSource());\n\n let readerCount = 0;\n let unsubscribeFromSource: (() => void) | undefined;\n const subscribe = (reader: SignalReader<Value>) => {\n const unsubscribe = derivedSignal.subscribe(reader);\n if (readerCount === 0) {\n unsubscribeFromSource = subscribeToSource(() => {\n derivedSignal.write(readFromSource());\n });\n }\n readerCount++;\n return () => {\n unsubscribe();\n readerCount--;\n if (readerCount === 0) {\n unsubscribeFromSource?.();\n unsubscribeFromSource = undefined;\n }\n };\n };\n\n const dispose = () => {\n unsubscribeFromSource?.();\n derivedSignal[Symbol.dispose]();\n };\n\n return { read: derivedSignal.read, subscribe, [Symbol.dispose]: dispose };\n};\n\nexport type SignalReader<Value> = ({\n value,\n previousValue,\n}: {\n value: Value;\n previousValue: Value;\n}) => void;\n"]}
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals/signals.ts"],"names":[],"mappings":"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","sourcesContent":["export const signal = <Value>(initialValue: Value): Signal<Value> => {\n const watchers = new Set<SignalWatcher<Value>>();\n let value = initialValue;\n\n const watch: SignalGetter<Value>[\"watch\"] = (watcher) => {\n watchers.add(watcher);\n return createUnwatch(() => {\n watchers.delete(watcher);\n });\n };\n\n const get: SignalGetter<Value> = () => value;\n get.watch = watch;\n\n const set: SignalSetter<Value> = (newValue) => {\n const oldValue = value;\n value = newValue;\n const update: SignalUpdate<Value> = {\n new: newValue,\n old: oldValue,\n };\n for (const watcher of watchers) {\n watcher(update);\n }\n };\n\n const dispose = () => {\n watchers.clear();\n };\n\n return { get, set, watch, [Symbol.dispose]: dispose };\n};\n\nsignal.from = <Value>(\n getFromSource: () => Value,\n subscribeToSource: (notify: () => void) => () => void,\n): Omit<Signal<Value>, \"set\"> => {\n const derivedSignal = signal(getFromSource());\n\n let watcherCount = 0;\n let unwatchFromSource: (() => void) | undefined;\n let disposed = false;\n const watch = (watcher: SignalWatcher<Value>) => {\n const unwatch = derivedSignal.watch(watcher);\n if (watcherCount === 0) {\n unwatchFromSource = subscribeToSource(() => {\n derivedSignal.set(getFromSource());\n });\n }\n watcherCount++;\n return createUnwatch(() => {\n if (disposed) {\n return;\n }\n unwatch();\n watcherCount--;\n if (watcherCount === 0) {\n unwatchFromSource?.();\n unwatchFromSource = undefined;\n }\n });\n };\n\n const get: SignalGetter<Value> = () => derivedSignal.get();\n get.watch = watch;\n\n const dispose = () => {\n if (disposed) {\n return;\n }\n disposed = true;\n unwatchFromSource?.();\n unwatchFromSource = undefined;\n watcherCount = 0;\n derivedSignal[Symbol.dispose]();\n };\n\n return { get, watch, [Symbol.dispose]: dispose };\n};\n\nconst createUnwatch = (remove: () => void): SignalUnwatch => {\n const unwatch = () => {\n remove();\n };\n unwatch[Symbol.dispose] = unwatch;\n return unwatch;\n};\n\nexport type SignalGetter<Value> = {\n (): Value;\n watch: (watcher: SignalWatcher<Value>) => SignalUnwatch;\n};\n\nexport type SignalWatcher<Value> = (update: SignalUpdate<Value>) => void;\n\nexport type SignalUpdate<Value> = {\n new: Value;\n old: Value;\n};\n\nexport type SignalSetter<Value> = (value: Value) => void;\n\nexport type SignalUnwatch = (() => void) & Disposable;\n\nexport type Signal<Value> = Disposable & {\n get: SignalGetter<Value>;\n set: SignalSetter<Value>;\n watch: SignalGetter<Value>[\"watch\"];\n};\n"]}
@@ -17,10 +17,10 @@ import { type Result } from "../result/result.ts";
17
17
  * const nullValue = unwrap(null, "default"); // "default"
18
18
  *
19
19
  * // With Result types
20
- * const success = result.success({ data: "success" });
20
+ * const success = result.success("success");
21
21
  * const data = unwrap(success); // "success"
22
22
  *
23
- * const error = result.error({ error: new Error("failed") });
23
+ * const error = result.error(new Error("failed"));
24
24
  * const fallback = unwrap(error, "default"); // "default"
25
25
  *
26
26
  * // With Promise.allSettled results
@@ -1 +1 @@
1
- {"version":3,"file":"unwrap.js","sourceRoot":"","sources":["../../src/unwrap/unwrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAkDlD,+DAA+D;AAC/D,MAAM,UAAU,MAAM,CACpB,UAA2E,EAC3E,QAAgB;IAEhB,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzC,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACpD,IAAI,WAAW;YAAE,OAAO,QAAS,CAAC;QAClC,MAAM,IAAI,SAAS,CAAC,GAAG,WAAW,YAAY,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACzB,uBAAuB;QACvB,IAAI,WAAW,IAAI,UAAU,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACtD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,IAAI,WAAW;oBAAE,OAAO,QAAS,CAAC;gBAClC,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,UAAU,CAAC,EAAE;oBACzD,KAAK,EAAE,UAAU;iBAClB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,UAAU,CAAC,IAAI,CAAC;QACzB,CAAC;QAED,qBAAqB;QACrB,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,WAAW;gBAAE,OAAO,QAAS,CAAC;YAClC,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,UAAU,CAAC,EAAE;gBACzD,KAAK,EAAE,UAAU;aAClB,CAAC,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACtC,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B,CAAC;QAED,IAAI,WAAW;YAAE,OAAO,QAAS,CAAC;QAClC,MAAM,UAAU,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,sBAAsB,GAAG,CAC7B,KAAc,EAC0B,EAAE,CAC1C,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,QAAQ,IAAI,KAAK;IACjB,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,OAAO,IAAI,KAAK,CAAC;QACjD,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC;AAExD,MAAM,WAAW,GAAG,iBAAiB,CAAC;AACtC,MAAM,yBAAyB,GAAG,CAAC,UAAmB,EAAE,EAAE,CACxD,GAAG,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,4CAA4C,CAAC","sourcesContent":["import { stringify } from \"../lib/string.ts\";\nimport { isResult } from \"../result/result.lib.ts\";\nimport { type Result } from \"../result/result.ts\";\n\n/**\n * Unwrap a value from Result or nullable types, returning the underlying value or throwing an error.\n *\n * This function safely extracts values from wrapped types like Result,\n * handling null/undefined values and providing fallback mechanisms.\n *\n * @param maybeValue - The value to unwrap (can be a plain value or Result)\n * @param fallback - Optional fallback value to return instead of throwing\n * @returns The unwrapped value or fallback\n * @throws {TypeError} When the value cannot be unwrapped and no fallback is provided\n *\n * @example\n * ```ts\n * // Basic unwrapping\n * const value = unwrap(\"hello\"); // \"hello\"\n * const nullValue = unwrap(null, \"default\"); // \"default\"\n *\n * // With Result types\n * const success = result.success({ data: \"success\" });\n * const data = unwrap(success); // \"success\"\n *\n * const error = result.error({ error: new Error(\"failed\") });\n * const fallback = unwrap(error, \"default\"); // \"default\"\n *\n * // With Promise.allSettled results\n * const settled = { status: \"fulfilled\", value: \"done\" } as const;\n * unwrap(settled); // \"done\"\n * ```\n */\nexport function unwrap<Value, GivenError extends Error>(\n maybeValue: Value | Result<Value, GivenError> | PromiseFulfilledResult<Value>,\n): Value;\nexport function unwrap<Value>(\n maybeValue: Result.Success<Value> | Result.Pending<Value>,\n fallback: unknown,\n): Value;\nexport function unwrap<Value, GivenError extends Error, const Fallback>(\n maybeValue: Result.Error<GivenError, Value>,\n fallback: Fallback,\n): Fallback;\nexport function unwrap<const Fallback>(\n maybeValue: PromiseRejectedResult,\n fallback: Fallback,\n): Fallback;\nexport function unwrap<Value, GivenError extends Error, const Fallback>(\n maybeValue: Value | Result<Value, GivenError> | PromiseSettledResult<Value>,\n fallback: Fallback,\n): NonNullable<Value> | Fallback;\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function unwrap<Value, GivenError extends Error, Fallback>(\n maybeValue: Value | Result<Value, GivenError> | PromiseSettledResult<Value>,\n fallback?: Value,\n): Value | Fallback {\n const hasFallback = arguments.length > 1;\n\n if (maybeValue === null || maybeValue === undefined) {\n if (hasFallback) return fallback!;\n throw new TypeError(`${errorPrefix}Value is ${stringify(maybeValue)}`);\n }\n\n if (isResult(maybeValue)) {\n // Handle pending state\n if (\"isPending\" in maybeValue && maybeValue.isPending) {\n if (maybeValue.data === undefined) {\n if (hasFallback) return fallback!;\n throw new TypeError(typeErrorMessageForResult(maybeValue), {\n cause: maybeValue,\n });\n }\n return maybeValue.data;\n }\n\n // Handle error state\n if (maybeValue.isError) {\n if (hasFallback) return fallback!;\n throw new TypeError(typeErrorMessageForResult(maybeValue), {\n cause: maybeValue,\n });\n }\n\n // Handle success state\n return maybeValue.data;\n }\n\n if (isPromiseSettledResult(maybeValue)) {\n if (maybeValue.status === \"fulfilled\") {\n return maybeValue.value;\n }\n\n if (hasFallback) return fallback!;\n throw maybeValue.reason;\n }\n\n return maybeValue;\n}\n\nconst isPromiseSettledResult = (\n value: unknown,\n): value is PromiseSettledResult<unknown> =>\n typeof value === \"object\" &&\n value !== null &&\n \"status\" in value &&\n ((value.status === \"fulfilled\" && \"value\" in value) ||\n (value.status === \"rejected\" && \"reason\" in value));\n\nconst errorPrefix = \"Cannot unwrap: \";\nconst typeErrorMessageForResult = (maybeValue: unknown) =>\n `${errorPrefix}${String(maybeValue)} is not a success and there is no fallback`;\n"]}
1
+ {"version":3,"file":"unwrap.js","sourceRoot":"","sources":["../../src/unwrap/unwrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAkDlD,+DAA+D;AAC/D,MAAM,UAAU,MAAM,CACpB,UAA2E,EAC3E,QAAgB;IAEhB,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzC,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACpD,IAAI,WAAW;YAAE,OAAO,QAAS,CAAC;QAClC,MAAM,IAAI,SAAS,CAAC,GAAG,WAAW,YAAY,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACzB,uBAAuB;QACvB,IAAI,WAAW,IAAI,UAAU,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACtD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,IAAI,WAAW;oBAAE,OAAO,QAAS,CAAC;gBAClC,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,UAAU,CAAC,EAAE;oBACzD,KAAK,EAAE,UAAU;iBAClB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,UAAU,CAAC,IAAI,CAAC;QACzB,CAAC;QAED,qBAAqB;QACrB,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,WAAW;gBAAE,OAAO,QAAS,CAAC;YAClC,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,UAAU,CAAC,EAAE;gBACzD,KAAK,EAAE,UAAU;aAClB,CAAC,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACtC,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B,CAAC;QAED,IAAI,WAAW;YAAE,OAAO,QAAS,CAAC;QAClC,MAAM,UAAU,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,sBAAsB,GAAG,CAC7B,KAAc,EAC0B,EAAE,CAC1C,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,QAAQ,IAAI,KAAK;IACjB,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,OAAO,IAAI,KAAK,CAAC;QACjD,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC;AAExD,MAAM,WAAW,GAAG,iBAAiB,CAAC;AACtC,MAAM,yBAAyB,GAAG,CAAC,UAAmB,EAAE,EAAE,CACxD,GAAG,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,4CAA4C,CAAC","sourcesContent":["import { stringify } from \"../lib/string.ts\";\nimport { isResult } from \"../result/result.lib.ts\";\nimport { type Result } from \"../result/result.ts\";\n\n/**\n * Unwrap a value from Result or nullable types, returning the underlying value or throwing an error.\n *\n * This function safely extracts values from wrapped types like Result,\n * handling null/undefined values and providing fallback mechanisms.\n *\n * @param maybeValue - The value to unwrap (can be a plain value or Result)\n * @param fallback - Optional fallback value to return instead of throwing\n * @returns The unwrapped value or fallback\n * @throws {TypeError} When the value cannot be unwrapped and no fallback is provided\n *\n * @example\n * ```ts\n * // Basic unwrapping\n * const value = unwrap(\"hello\"); // \"hello\"\n * const nullValue = unwrap(null, \"default\"); // \"default\"\n *\n * // With Result types\n * const success = result.success(\"success\");\n * const data = unwrap(success); // \"success\"\n *\n * const error = result.error(new Error(\"failed\"));\n * const fallback = unwrap(error, \"default\"); // \"default\"\n *\n * // With Promise.allSettled results\n * const settled = { status: \"fulfilled\", value: \"done\" } as const;\n * unwrap(settled); // \"done\"\n * ```\n */\nexport function unwrap<Value, GivenError extends Error>(\n maybeValue: Value | Result<Value, GivenError> | PromiseFulfilledResult<Value>,\n): Value;\nexport function unwrap<Value>(\n maybeValue: Result.Success<Value> | Result.Pending<Value>,\n fallback: unknown,\n): Value;\nexport function unwrap<Value, GivenError extends Error, const Fallback>(\n maybeValue: Result.Error<GivenError, Value>,\n fallback: Fallback,\n): Fallback;\nexport function unwrap<const Fallback>(\n maybeValue: PromiseRejectedResult,\n fallback: Fallback,\n): Fallback;\nexport function unwrap<Value, GivenError extends Error, const Fallback>(\n maybeValue: Value | Result<Value, GivenError> | PromiseSettledResult<Value>,\n fallback: Fallback,\n): NonNullable<Value> | Fallback;\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function unwrap<Value, GivenError extends Error, Fallback>(\n maybeValue: Value | Result<Value, GivenError> | PromiseSettledResult<Value>,\n fallback?: Value,\n): Value | Fallback {\n const hasFallback = arguments.length > 1;\n\n if (maybeValue === null || maybeValue === undefined) {\n if (hasFallback) return fallback!;\n throw new TypeError(`${errorPrefix}Value is ${stringify(maybeValue)}`);\n }\n\n if (isResult(maybeValue)) {\n // Handle pending state\n if (\"isPending\" in maybeValue && maybeValue.isPending) {\n if (maybeValue.data === undefined) {\n if (hasFallback) return fallback!;\n throw new TypeError(typeErrorMessageForResult(maybeValue), {\n cause: maybeValue,\n });\n }\n return maybeValue.data;\n }\n\n // Handle error state\n if (maybeValue.isError) {\n if (hasFallback) return fallback!;\n throw new TypeError(typeErrorMessageForResult(maybeValue), {\n cause: maybeValue,\n });\n }\n\n // Handle success state\n return maybeValue.data;\n }\n\n if (isPromiseSettledResult(maybeValue)) {\n if (maybeValue.status === \"fulfilled\") {\n return maybeValue.value;\n }\n\n if (hasFallback) return fallback!;\n throw maybeValue.reason;\n }\n\n return maybeValue;\n}\n\nconst isPromiseSettledResult = (\n value: unknown,\n): value is PromiseSettledResult<unknown> =>\n typeof value === \"object\" &&\n value !== null &&\n \"status\" in value &&\n ((value.status === \"fulfilled\" && \"value\" in value) ||\n (value.status === \"rejected\" && \"reason\" in value));\n\nconst errorPrefix = \"Cannot unwrap: \";\nconst typeErrorMessageForResult = (maybeValue: unknown) =>\n `${errorPrefix}${String(maybeValue)} is not a success and there is no fallback`;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerigon/typescript-toolkit",
3
- "version": "2.2.0",
3
+ "version": "4.0.0",
4
4
  "description": "🔧✨ Tiny helpers for TypeScript applications",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/peerigon/typescript-toolkit#readme",
@@ -16,7 +16,6 @@
16
16
  "sideEffects": false,
17
17
  "type": "module",
18
18
  "exports": {
19
- ".": "./dist/main.js",
20
19
  "./assert": "./dist/assert/assert.js",
21
20
  "./dedupe": "./dist/dedupe/dedupe.js",
22
21
  "./emitter": "./dist/emitter/emitter.js",
@@ -27,7 +26,6 @@
27
26
  "./signals": "./dist/signals/signals.js",
28
27
  "./unwrap": "./dist/unwrap/unwrap.js"
29
28
  },
30
- "main": "./dist/main.js",
31
29
  "files": [
32
30
  "dist",
33
31
  "README.md"
@@ -42,6 +40,7 @@
42
40
  "test:jsr": "jsr publish --dry-run --allow-dirty",
43
41
  "test:build": "run-s build test:build:*",
44
42
  "test:build:size": "size-limit",
43
+ "test:build:publishable": "verify-publishable",
45
44
  "vitest": "vitest",
46
45
  "build": "run-s build:*",
47
46
  "build:clear": "rimraf dist",
@@ -54,26 +53,33 @@
54
53
  },
55
54
  "devDependencies": {
56
55
  "@djankies/vitest-mcp": "0.5.1",
57
- "@eslint/mcp": "0.3.5",
58
- "@peerigon/configs": "^15.4.0",
56
+ "@eslint/mcp": "0.3.7",
57
+ "@peerigon/configs": "^18.1.2",
59
58
  "@secretlint/secretlint-rule-preset-recommend": "^13.0.2",
60
59
  "@size-limit/preset-small-lib": "^12.1.0",
61
60
  "@tanstack/query-core": "^5.100.11",
62
- "@types/node": "^25.8.0",
63
- "@vitest/coverage-v8": "^4.1.6",
61
+ "@types/node": "^26.0.1",
62
+ "@vitest/coverage-v8": "^4.1.9",
64
63
  "eslint": "^9.39.2",
65
64
  "husky": "^9.1.7",
66
65
  "jsr": "^0.14.3",
67
- "lint-staged": "^17.0.4",
68
- "npm-run-all2": "^8.0.4",
66
+ "lint-staged": "^17.0.8",
67
+ "npm-run-all2": "^9.0.2",
69
68
  "pin-github-action": "^3.4.0",
70
- "prettier": "^3.8.3",
69
+ "prettier": "^3.9.0",
71
70
  "rimraf": "^6.0.1",
72
71
  "secretlint": "^13.0.2",
73
72
  "semantic-release": "^25.0.3",
74
73
  "ts-lsp-mcp": "0.1.3",
75
- "typescript": "^5.9.3",
76
- "vitest": "^4.1.6"
74
+ "typescript": "^6.0.3",
75
+ "vitest": "^4.1.9"
76
+ },
77
+ "devEngines": {
78
+ "runtime": {
79
+ "name": "node",
80
+ "version": "24.18.0",
81
+ "onFail": "error"
82
+ }
77
83
  },
78
84
  "publishConfig": {
79
85
  "access": "public",
package/dist/main.d.ts DELETED
@@ -1,6 +0,0 @@
1
- export * from "./assert/assert.ts";
2
- export * from "./dedupe/dedupe.ts";
3
- export * from "./enums/enums.ts";
4
- export * from "./match/match.ts";
5
- export * from "./need/need.ts";
6
- //# sourceMappingURL=main.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
package/dist/main.js DELETED
@@ -1,6 +0,0 @@
1
- export * from "./assert/assert.js";
2
- export * from "./dedupe/dedupe.js";
3
- export * from "./enums/enums.js";
4
- export * from "./match/match.js";
5
- export * from "./need/need.js";
6
- //# sourceMappingURL=main.js.map
package/dist/main.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from \"./assert/assert.ts\";\nexport * from \"./dedupe/dedupe.ts\";\nexport * from \"./enums/enums.ts\";\nexport * from \"./match/match.ts\";\nexport * from \"./need/need.ts\";\n"]}