@soundscript/soundscript 0.1.15 → 0.1.16

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/decode.d.ts CHANGED
@@ -8,11 +8,11 @@ export class DecodeFailure extends Failure {
8
8
  readonly path: DecodePath;
9
9
  constructor(
10
10
  message?: string,
11
- options?: {
11
+ options?: Readonly<{
12
12
  cause?: unknown;
13
13
  path?: DecodePath;
14
14
  trace?: readonly ErrorFrame[];
15
- },
15
+ }>,
16
16
  );
17
17
  at(segment: DecodePathSegment): this;
18
18
  }
package/decode.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"decode.js","sourceRoot":"","sources":["./soundscript/decode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, none, ok, some, type Option, type Result } from '@soundscript/soundscript/result';\n\nexport type DecodePathSegment = string | number;\nexport type DecodePath = readonly DecodePathSegment[];\n\nexport class DecodeFailure extends Failure {\n readonly path: DecodePath;\n\n constructor(\n message = 'Failed to decode value.',\n options: {\n cause?: unknown;\n path?: DecodePath;\n trace?: readonly ErrorFrame[];\n } = {},\n ) {\n super(message, {\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n ...(options.trace === undefined ? {} : { trace: options.trace }),\n });\n this.path = options.path ?? [];\n }\n\n at(segment: DecodePathSegment): this {\n const prototype = Object.getPrototypeOf(this as object);\n const clone = (prototype === null ? Object.create(null) : Object.create(prototype)) as this;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));\n Object.defineProperty(clone, 'path', {\n configurable: true,\n enumerable: true,\n writable: false,\n value: [segment, ...this.path],\n });\n return clone;\n }\n}\n\n// #[variance(T: out, E: out)]\nexport type Decoder<T, E = DecodeFailure> = {\n decode(value: unknown): Result<T, E>;\n};\n\n// #[variance(T: out, E: out)]\nexport type OptionalDecoder<T, E = DecodeFailure> = Decoder<T | undefined, E> & {\n readonly __soundscriptOptional: true;\n readonly inner: Decoder<T, E>;\n};\n\ntype DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;\ntype DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;\n\ntype ObjectShape = Record<string, Decoder<unknown, unknown>>;\ntype TupleShape = readonly Decoder<unknown, unknown>[];\n\nexport const string: Decoder<string> = {\n decode(value): Result<string, DecodeFailure> {\n return typeof value === 'string'\n ? ok(value)\n : err(new DecodeFailure('Expected string.', { cause: value }));\n },\n};\n\nexport const number: Decoder<number> = {\n decode(value): Result<number, DecodeFailure> {\n return typeof value === 'number'\n ? ok(value)\n : err(new DecodeFailure('Expected number.', { cause: value }));\n },\n};\n\nexport const boolean: Decoder<boolean> = {\n decode(value): Result<boolean, DecodeFailure> {\n return typeof value === 'boolean'\n ? ok(value)\n : err(new DecodeFailure('Expected boolean.', { cause: value }));\n },\n};\n\nexport const bigint: Decoder<bigint> = {\n decode(value): Result<bigint, DecodeFailure> {\n if (typeof value === 'bigint') {\n return ok(value);\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) && Number.isSafeInteger(value)\n ? ok(BigInt(value))\n : err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n\n if (typeof value === 'string') {\n try {\n return ok(BigInt(value));\n } catch {\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n }\n\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n },\n};\n\nexport function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E> {\n return {\n decode(value) {\n return getDecoder().decode(value);\n },\n };\n}\n\nexport function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E> {\n return {\n __soundscriptOptional: true,\n inner: decoder,\n decode(value) {\n return value === undefined ? ok(undefined) : decoder.decode(value);\n },\n };\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Decoder<T> {\n return {\n decode(input) {\n return Object.is(input, value)\n ? ok(value)\n : err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));\n },\n };\n}\n\nexport function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected array.', { cause: value }));\n }\n\n const decodedValues: T[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const decoded = item.decode(value[index]);\n if (isErr(decoded)) {\n return err(prependPathIfPossible(decoded.error, index));\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues);\n },\n };\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Decoder<\n { readonly [K in keyof TElements]: DecoderValue<TElements[K]> },\n DecoderError<TElements[number]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected tuple.', { cause: value }));\n }\n\n if (value.length !== elements.length) {\n return err(\n new DecodeFailure(`Expected tuple of length ${elements.length}.`, {\n cause: value,\n }),\n );\n }\n\n const decodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementDecoder = elements[index];\n if (!elementDecoder) {\n continue;\n }\n const decoded = elementDecoder.decode(value[index]);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, index) as\n | DecoderError<TElements[number]>\n | DecodeFailure,\n );\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues as { readonly [K in keyof TElements]: DecoderValue<TElements[K]> });\n },\n };\n}\n\nexport function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('some'),\n value: item,\n }),\n (value) => some(value.value) as Option<T>,\n ),\n map(\n object({\n tag: literal('none'),\n }),\n () => none() as Option<T>,\n ),\n );\n}\n\nexport function result<T, EValue, EDecodeValue, EDecodeError>(\n okDecoder: Decoder<T, EDecodeValue>,\n errDecoder: Decoder<EValue, EDecodeError>,\n): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: okDecoder,\n }),\n (value) => ok(value.value) as Result<T, EValue>,\n ),\n map(\n object({\n tag: literal('err'),\n error: errDecoder,\n }),\n (value) => err(value.error) as Result<T, EValue>,\n ),\n );\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Decoder<\n { readonly [K in keyof TShape]: DecoderValue<TShape[K]> },\n DecoderError<TShape[keyof TShape]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!isPlainObject(value)) {\n return err(new DecodeFailure('Expected object.', { cause: value }));\n }\n\n const record = value as Record<string, unknown>;\n const decodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const decoder = shape[key];\n if (!decoder) {\n continue;\n }\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalDecoder(decoder)) {\n decodedObject[key] = undefined;\n continue;\n }\n\n return err(\n new DecodeFailure(`Missing field \"${key}\".`, {\n cause: value,\n path: [key],\n }),\n );\n }\n\n const decoded = decoder.decode(rawValue);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, key) as\n | DecoderError<TShape[keyof TShape]>\n | DecodeFailure,\n );\n }\n\n decodedObject[key] = decoded.value;\n }\n\n return ok(decodedObject as { readonly [K in keyof TShape]: DecoderValue<TShape[K]> });\n },\n };\n}\n\nexport function field<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T, E | DecodeFailure> {\n const shape = { [key]: decoder } as { readonly [P in K]: Decoder<T, E> };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function optionalField<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T | undefined, E | DecodeFailure> {\n const shape = { [key]: optional(decoder) } as {\n readonly [P in K]: OptionalDecoder<T, E>;\n };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function union<A, B, ELeft, ERight>(\n left: Decoder<A, ELeft>,\n right: Decoder<B, ERight>,\n): Decoder<A | B, ELeft | ERight | DecodeFailure> {\n return {\n decode(value) {\n const leftDecoded = left.decode(value);\n if (isErr(leftDecoded)) {\n const rightDecoded = right.decode(value);\n if (isErr(rightDecoded)) {\n return err(\n new DecodeFailure('Expected one of the union members.', {\n cause: value,\n }),\n );\n }\n return rightDecoded;\n }\n return leftDecoded;\n },\n };\n}\n\nexport function map<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => B,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : ok(project(decoded.value));\n },\n };\n}\n\nexport function andThen<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => Decoder<B, E>,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));\n },\n };\n}\n\nexport function refine<A, B extends A, E>(\n decoder: Decoder<A, E>,\n predicate: (value: A) => value is B,\n message: string,\n): Decoder<B, E | DecodeFailure> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n if (isErr(decoded)) {\n return decoded;\n }\n\n return predicate(decoded.value)\n ? ok(decoded.value)\n : err(new DecodeFailure(message, { cause: value }));\n },\n };\n}\n\nfunction prependPathIfPossible<E>(error: E, segment: DecodePathSegment): E | DecodeFailure {\n return error instanceof DecodeFailure ? error.at(segment) : error;\n}\n\nfunction isOptionalDecoder(\n value: Decoder<unknown, unknown>,\n): value is OptionalDecoder<unknown, unknown> {\n return '__soundscriptOptional' in value &&\n value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction valueOf<T>(decoded: { readonly value: T }): T {\n return decoded.value;\n}\n"]}
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["./soundscript/decode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, none, ok, some, type Option, type Result } from '@soundscript/soundscript/result';\n\nexport type DecodePathSegment = string | number;\nexport type DecodePath = readonly DecodePathSegment[];\n\nexport class DecodeFailure extends Failure {\n readonly path: DecodePath;\n\n constructor(\n message = 'Failed to decode value.',\n options: Readonly<{\n cause?: unknown;\n path?: DecodePath;\n trace?: readonly ErrorFrame[];\n }> = {},\n ) {\n super(message, {\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n ...(options.trace === undefined ? {} : { trace: options.trace }),\n });\n this.path = options.path ?? [];\n }\n\n at(segment: DecodePathSegment): this {\n const prototype = Object.getPrototypeOf(this as object);\n const clone = (prototype === null ? Object.create(null) : Object.create(prototype)) as this;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));\n Object.defineProperty(clone, 'path', {\n configurable: true,\n enumerable: true,\n writable: false,\n value: [segment, ...this.path],\n });\n return clone;\n }\n}\n\n// #[variance(T: out, E: out)]\nexport type Decoder<T, E = DecodeFailure> = {\n decode(value: unknown): Result<T, E>;\n};\n\n// #[variance(T: out, E: out)]\nexport type OptionalDecoder<T, E = DecodeFailure> = Decoder<T | undefined, E> & {\n readonly __soundscriptOptional: true;\n readonly inner: Decoder<T, E>;\n};\n\ntype DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;\ntype DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;\n\ntype ObjectShape = Record<string, Decoder<unknown, unknown>>;\ntype TupleShape = readonly Decoder<unknown, unknown>[];\n\nexport const string: Decoder<string> = {\n decode(value): Result<string, DecodeFailure> {\n return typeof value === 'string'\n ? ok(value)\n : err(new DecodeFailure('Expected string.', { cause: value }));\n },\n};\n\nexport const number: Decoder<number> = {\n decode(value): Result<number, DecodeFailure> {\n return typeof value === 'number'\n ? ok(value)\n : err(new DecodeFailure('Expected number.', { cause: value }));\n },\n};\n\nexport const boolean: Decoder<boolean> = {\n decode(value): Result<boolean, DecodeFailure> {\n return typeof value === 'boolean'\n ? ok(value)\n : err(new DecodeFailure('Expected boolean.', { cause: value }));\n },\n};\n\nexport const bigint: Decoder<bigint> = {\n decode(value): Result<bigint, DecodeFailure> {\n if (typeof value === 'bigint') {\n return ok(value);\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) && Number.isSafeInteger(value)\n ? ok(BigInt(value))\n : err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n\n if (typeof value === 'string') {\n try {\n return ok(BigInt(value));\n } catch {\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n }\n\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n },\n};\n\nexport function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E> {\n return {\n decode(value) {\n return getDecoder().decode(value);\n },\n };\n}\n\nexport function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E> {\n return {\n __soundscriptOptional: true,\n inner: decoder,\n decode(value) {\n return value === undefined ? ok(undefined) : decoder.decode(value);\n },\n };\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Decoder<T> {\n return {\n decode(input) {\n return Object.is(input, value)\n ? ok(value)\n : err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));\n },\n };\n}\n\nexport function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected array.', { cause: value }));\n }\n\n const decodedValues: T[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const decoded = item.decode(value[index]);\n if (isErr(decoded)) {\n return err(prependPathIfPossible(decoded.error, index));\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues);\n },\n };\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Decoder<\n { readonly [K in keyof TElements]: DecoderValue<TElements[K]> },\n DecoderError<TElements[number]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected tuple.', { cause: value }));\n }\n\n if (value.length !== elements.length) {\n return err(\n new DecodeFailure(`Expected tuple of length ${elements.length}.`, {\n cause: value,\n }),\n );\n }\n\n const decodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementDecoder = elements[index];\n if (!elementDecoder) {\n continue;\n }\n const decoded = elementDecoder.decode(value[index]);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, index) as\n | DecoderError<TElements[number]>\n | DecodeFailure,\n );\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues as { readonly [K in keyof TElements]: DecoderValue<TElements[K]> });\n },\n };\n}\n\nexport function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('some'),\n value: item,\n }),\n (value) => some(value.value) as Option<T>,\n ),\n map(\n object({\n tag: literal('none'),\n }),\n () => none() as Option<T>,\n ),\n );\n}\n\nexport function result<T, EValue, EDecodeValue, EDecodeError>(\n okDecoder: Decoder<T, EDecodeValue>,\n errDecoder: Decoder<EValue, EDecodeError>,\n): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: okDecoder,\n }),\n (value) => ok(value.value) as Result<T, EValue>,\n ),\n map(\n object({\n tag: literal('err'),\n error: errDecoder,\n }),\n (value) => err(value.error) as Result<T, EValue>,\n ),\n );\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Decoder<\n { readonly [K in keyof TShape]: DecoderValue<TShape[K]> },\n DecoderError<TShape[keyof TShape]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!isPlainObject(value)) {\n return err(new DecodeFailure('Expected object.', { cause: value }));\n }\n\n const record = value as Record<string, unknown>;\n const decodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const decoder = shape[key];\n if (!decoder) {\n continue;\n }\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalDecoder(decoder)) {\n decodedObject[key] = undefined;\n continue;\n }\n\n return err(\n new DecodeFailure(`Missing field \"${key}\".`, {\n cause: value,\n path: [key],\n }),\n );\n }\n\n const decoded = decoder.decode(rawValue);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, key) as\n | DecoderError<TShape[keyof TShape]>\n | DecodeFailure,\n );\n }\n\n decodedObject[key] = decoded.value;\n }\n\n return ok(decodedObject as { readonly [K in keyof TShape]: DecoderValue<TShape[K]> });\n },\n };\n}\n\nexport function field<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T, E | DecodeFailure> {\n const shape = { [key]: decoder } as { readonly [P in K]: Decoder<T, E> };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function optionalField<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T | undefined, E | DecodeFailure> {\n const shape = { [key]: optional(decoder) } as {\n readonly [P in K]: OptionalDecoder<T, E>;\n };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function union<A, B, ELeft, ERight>(\n left: Decoder<A, ELeft>,\n right: Decoder<B, ERight>,\n): Decoder<A | B, ELeft | ERight | DecodeFailure> {\n return {\n decode(value) {\n const leftDecoded = left.decode(value);\n if (isErr(leftDecoded)) {\n const rightDecoded = right.decode(value);\n if (isErr(rightDecoded)) {\n return err(\n new DecodeFailure('Expected one of the union members.', {\n cause: value,\n }),\n );\n }\n return rightDecoded;\n }\n return leftDecoded;\n },\n };\n}\n\nexport function map<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => B,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : ok(project(decoded.value));\n },\n };\n}\n\nexport function andThen<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => Decoder<B, E>,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));\n },\n };\n}\n\nexport function refine<A, B extends A, E>(\n decoder: Decoder<A, E>,\n predicate: (value: A) => value is B,\n message: string,\n): Decoder<B, E | DecodeFailure> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n if (isErr(decoded)) {\n return decoded;\n }\n\n return predicate(decoded.value)\n ? ok(decoded.value)\n : err(new DecodeFailure(message, { cause: value }));\n },\n };\n}\n\nfunction prependPathIfPossible<E>(error: E, segment: DecodePathSegment): E | DecodeFailure {\n return error instanceof DecodeFailure ? error.at(segment) : error;\n}\n\nfunction isOptionalDecoder(\n value: Decoder<unknown, unknown>,\n): value is OptionalDecoder<unknown, unknown> {\n return '__soundscriptOptional' in value &&\n value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction valueOf<T>(decoded: { readonly value: T }): T {\n return decoded.value;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soundscript/soundscript",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -232,11 +232,11 @@
232
232
  "typescript": "5.9.3"
233
233
  },
234
234
  "optionalDependencies": {
235
- "@soundscript/cli-darwin-arm64": "0.1.15",
236
- "@soundscript/cli-darwin-x64": "0.1.15",
237
- "@soundscript/cli-linux-arm64": "0.1.15",
238
- "@soundscript/cli-linux-x64": "0.1.15",
239
- "@soundscript/cli-win32-x64": "0.1.15"
235
+ "@soundscript/cli-darwin-arm64": "0.1.16",
236
+ "@soundscript/cli-darwin-x64": "0.1.16",
237
+ "@soundscript/cli-linux-arm64": "0.1.16",
238
+ "@soundscript/cli-linux-x64": "0.1.16",
239
+ "@soundscript/cli-win32-x64": "0.1.16"
240
240
  },
241
241
  "repository": {
242
242
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  import ts from 'typescript';
2
- import { bindFunctionBindingName, appendSegment, arrayMutationCallAffectsNarrow, assignmentAffectsNarrow, bindFunctionReceiverPath, cloneState, getCalledMember, getExpressionSymbol, getFunctionBindings, getFunctionBodyCalledMember, getFunctionLikeFromBoundMemberCall, getFunctionLikeFromBoundValue, getFunctionLikeFromCallExpression, getStateExpressionBoundValue, getUniformArrayElementBindingFromExpression, getUniformArrayElementBindingFromFunctionBodyExpression, getUniformMapEntryBindingsFromExpression, getUniformMapEntryBindingsFromFunctionBodyExpression, getUniformSetElementBindingFromExpression, getUniformSetElementBindingFromFunctionBodyExpression, getNestedFunctionBindings, getMutableBindingSymbol, getShorthandStateBoundValue, getSymbolId, getUpdateExpressionOperand, isConstLocalBindingPath, isFunctionLikeWithBody, isLocalBindingPath, isStableConstLocalBindingPath, MUTATING_ASSIGNMENT_OPERATORS, mutationAffectsNarrow, normalizeExpressionPath, normalizeExpressionSourcePath, normalizeFunctionBodyPath, opaqueArgumentEscapeAffectsNarrow, pathsMatch, recordForOfLoopHeaderAliases, recordFunctionBodyConstBindings, recordExecutedExpressionAliases, recordVariableAliases, typeMayAliasMutableState, typedUpdateExpressionAffectsNarrow, } from './flow_shared.js';
2
+ import { bindFunctionBindingName, appendSegment, arrayMutationCallAffectsNarrow, assignmentAffectsNarrow, bindFunctionReceiverPath, cloneState, getCalledMember, getExpressionSymbol, getFunctionBindings, getFunctionBodyCalledMember, getFunctionLikeFromExpression, getFunctionLikeFromBoundMemberCall, getFunctionLikeFromBoundValue, getFunctionLikeFromCallExpression, getStateExpressionBoundValue, getUniformArrayElementBindingFromExpression, getUniformArrayElementBindingFromFunctionBodyExpression, getUniformMapEntryBindingsFromExpression, getUniformMapEntryBindingsFromFunctionBodyExpression, getUniformSetElementBindingFromExpression, getUniformSetElementBindingFromFunctionBodyExpression, getNestedFunctionBindings, getMutableBindingSymbol, getShorthandStateBoundValue, getSymbolId, getUpdateExpressionOperand, isConstLocalBindingPath, isFunctionLikeWithBody, isLocalBindingPath, isStableConstLocalBindingPath, MUTATING_ASSIGNMENT_OPERATORS, mutationAffectsNarrow, normalizeExpressionPath, normalizeExpressionSourcePath, normalizeFunctionBodyPath, opaqueArgumentEscapeAffectsNarrow, pathsMatch, recordForOfLoopHeaderAliases, recordFunctionBodyConstBindings, recordExecutedExpressionAliases, recordVariableAliases, typeMayAliasMutableState, typedUpdateExpressionAffectsNarrow, } from './flow_shared.js';
3
3
  export { appendSegment, cloneState, isFunctionLikeWithBody, normalizeExpressionPath, recordExecutedExpressionAliases, recordVariableAliases, } from './flow_shared.js';
4
4
  const SYNCHRONOUS_ARRAY_CALLBACK_PARAMETER_BINDINGS = new Map([
5
5
  ['every', { callbackArgumentIndex: 0, elementParameterIndex: 0, arrayParameterIndex: 2 }],
@@ -389,10 +389,22 @@ function getLocalCallbackFunctionLike(context, expression, bindings) {
389
389
  }
390
390
  const symbol = getExpressionSymbol(context, expression);
391
391
  if (!symbol) {
392
- return undefined;
392
+ return getFunctionLikeFromExpression(context, expression);
393
393
  }
394
394
  const boundValue = bindings.boundValues.get(getSymbolId(context, symbol));
395
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
395
+ return boundValue
396
+ ? getFunctionLikeFromBoundValue(context, boundValue)
397
+ : getFunctionLikeFromExpression(context, expression);
398
+ }
399
+ function getStateCallbackFunctionLike(context, expression, state) {
400
+ expression = unwrapTransparentExpression(expression);
401
+ if (isFunctionLikeWithBody(expression)) {
402
+ return expression;
403
+ }
404
+ const boundValue = getStateExpressionBoundValue(context, expression, state);
405
+ return boundValue
406
+ ? getFunctionLikeFromBoundValue(context, boundValue)
407
+ : getFunctionLikeFromExpression(context, expression);
396
408
  }
397
409
  function arrayCallbackArgumentAffectsNarrow(context, receiver, member, callExpression, bindings, narrowPath, state) {
398
410
  const callbackBinding = member
@@ -437,12 +449,7 @@ function arrayCallbackExpressionAffectsNarrow(context, receiver, member, callExp
437
449
  if (!callbackArgument) {
438
450
  return false;
439
451
  }
440
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
441
- ? callbackArgument
442
- : (() => {
443
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
444
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
445
- })();
452
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
446
453
  if (!callbackDeclaration) {
447
454
  return false;
448
455
  }
@@ -509,12 +516,7 @@ function setCallbackExpressionAffectsNarrow(context, receiver, member, callExpre
509
516
  if (!callbackArgument) {
510
517
  return false;
511
518
  }
512
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
513
- ? callbackArgument
514
- : (() => {
515
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
516
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
517
- })();
519
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
518
520
  if (!callbackDeclaration) {
519
521
  return false;
520
522
  }
@@ -589,12 +591,7 @@ function mapCallbackExpressionAffectsNarrow(context, receiver, member, callExpre
589
591
  if (!callbackArgument) {
590
592
  return false;
591
593
  }
592
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
593
- ? callbackArgument
594
- : (() => {
595
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
596
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
597
- })();
594
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
598
595
  if (!callbackDeclaration) {
599
596
  return false;
600
597
  }
@@ -21,6 +21,7 @@ import {
21
21
  getExpressionSymbol,
22
22
  getFunctionBindings,
23
23
  getFunctionBodyCalledMember,
24
+ getFunctionLikeFromExpression,
24
25
  getFunctionLikeFromBoundMemberCall,
25
26
  getFunctionLikeFromBoundValue,
26
27
  getFunctionLikeFromCallExpression,
@@ -766,11 +767,30 @@ function getLocalCallbackFunctionLike(
766
767
 
767
768
  const symbol = getExpressionSymbol(context, expression);
768
769
  if (!symbol) {
769
- return undefined;
770
+ return getFunctionLikeFromExpression(context, expression);
770
771
  }
771
772
 
772
773
  const boundValue = bindings.boundValues.get(getSymbolId(context, symbol));
773
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
774
+ return boundValue
775
+ ? getFunctionLikeFromBoundValue(context, boundValue)
776
+ : getFunctionLikeFromExpression(context, expression);
777
+ }
778
+
779
+ function getStateCallbackFunctionLike(
780
+ context: AnalysisContext,
781
+ expression: ts.Expression,
782
+ state: AnalysisState,
783
+ ): ts.FunctionLikeDeclaration | undefined {
784
+ expression = unwrapTransparentExpression(expression);
785
+
786
+ if (isFunctionLikeWithBody(expression)) {
787
+ return expression;
788
+ }
789
+
790
+ const boundValue = getStateExpressionBoundValue(context, expression, state);
791
+ return boundValue
792
+ ? getFunctionLikeFromBoundValue(context, boundValue)
793
+ : getFunctionLikeFromExpression(context, expression);
774
794
  }
775
795
 
776
796
  function arrayCallbackArgumentAffectsNarrow(
@@ -865,12 +885,7 @@ function arrayCallbackExpressionAffectsNarrow(
865
885
  return false;
866
886
  }
867
887
 
868
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
869
- ? callbackArgument
870
- : (() => {
871
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
872
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
873
- })();
888
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
874
889
  if (!callbackDeclaration) {
875
890
  return false;
876
891
  }
@@ -1016,12 +1031,7 @@ function setCallbackExpressionAffectsNarrow(
1016
1031
  return false;
1017
1032
  }
1018
1033
 
1019
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
1020
- ? callbackArgument
1021
- : (() => {
1022
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
1023
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
1024
- })();
1034
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
1025
1035
  if (!callbackDeclaration) {
1026
1036
  return false;
1027
1037
  }
@@ -1183,12 +1193,7 @@ function mapCallbackExpressionAffectsNarrow(
1183
1193
  return false;
1184
1194
  }
1185
1195
 
1186
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
1187
- ? callbackArgument
1188
- : (() => {
1189
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
1190
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
1191
- })();
1196
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
1192
1197
  if (!callbackDeclaration) {
1193
1198
  return false;
1194
1199
  }
@@ -1325,7 +1325,8 @@ function isInstalledSoundStdlibSourceFile(sourceFile) {
1325
1325
  const normalizedFileName = sourceFile.fileName.replaceAll('\\', '/');
1326
1326
  return normalizedFileName.includes('/node_modules/@soundscript/soundscript/') &&
1327
1327
  (normalizedFileName.endsWith('.d.ts') ||
1328
- normalizedFileName.endsWith('.sts'));
1328
+ normalizedFileName.endsWith('.sts') ||
1329
+ normalizedFileName.endsWith('.sts.ts'));
1329
1330
  }
1330
1331
  function isLocalBuiltinSoundStdlibSourceFile(sourceFile) {
1331
1332
  const normalizedFileName = sourceFile.fileName.replaceAll('\\', '/');
@@ -3214,10 +3215,21 @@ function classifyCurrentTypeNodeNewtypeRelation(context, sourceType, targetType,
3214
3215
  return createNominalNewtypeRelationMismatch(context, sourceType, targetType, targetIdentitySet);
3215
3216
  }
3216
3217
  function classifyCurrentTypeNodeNominalClassRelation(context, sourceType, targetType, targetTypeNode, sourceExpression, sourceTypeNode) {
3218
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3219
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3220
+ sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3221
+ sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3222
+ return undefined;
3223
+ }
3217
3224
  const targetIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, targetTypeNode);
3218
3225
  if (!targetIdentitySet) {
3219
3226
  return undefined;
3220
3227
  }
3228
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3229
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
3230
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
3231
+ return undefined;
3232
+ }
3221
3233
  const sourceIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, sourceTypeNode) ??
3222
3234
  getDeclaredClassIdentitySetFromExpression(context, sourceExpression);
3223
3235
  if (sourceIdentitySet &&
@@ -3506,6 +3518,11 @@ function sourceNewtypeMatchesTargetIdentity(context, sourceType, targetIdentity)
3506
3518
  });
3507
3519
  }
3508
3520
  function classifySourceTypeAgainstTargetClassIdentitySet(context, sourceType, targetType, targetIdentitySet) {
3521
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3522
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
3523
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
3524
+ return undefined;
3525
+ }
3509
3526
  if (targetIdentitySet.mode === 'union') {
3510
3527
  const normalizedSourceType = getSafeNonNullableRelationType(context, sourceType);
3511
3528
  if ((normalizedSourceType.flags & ts.TypeFlags.Never) !== 0) {
@@ -3562,7 +3579,8 @@ function classifySourceTypeAgainstTargetClassIdentitySet(context, sourceType, ta
3562
3579
  return undefined;
3563
3580
  }
3564
3581
  function classifyUnsoundNominalClassRelation(context, sourceType, targetType) {
3565
- if (sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3582
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3583
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3566
3584
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3567
3585
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3568
3586
  return undefined;
@@ -3606,7 +3624,8 @@ function classifyUnsoundNominalNewtypeRelation(context, sourceType, targetType,
3606
3624
  return undefined;
3607
3625
  }
3608
3626
  function classifyUnsoundGenericClassInstanceRelation(context, sourceType, targetType) {
3609
- if (sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3627
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3628
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3610
3629
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3611
3630
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3612
3631
  return undefined;
@@ -3683,6 +3702,141 @@ function sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType
3683
3702
  return sourceIdentitySet.identities.length === targetIdentitySet.identities.length &&
3684
3703
  sourceIdentitySet.identities.every((sourceIdentity) => targetIdentitySet.identities.some((targetIdentity) => classIdentitiesMatch(context, sourceIdentity, targetIdentity)));
3685
3704
  }
3705
+ function isTrustedResultStdlibSourceFileName(fileName) {
3706
+ return /(?:^|[\\/])(?:index|result)(?:\.sts)?(?:\.d)?\.ts$/.test(fileName);
3707
+ }
3708
+ function getCanonicalResultClassFamilyForName(name) {
3709
+ switch (name) {
3710
+ case 'Err':
3711
+ case 'Ok':
3712
+ case 'Result':
3713
+ return 'result';
3714
+ case 'None':
3715
+ case 'Option':
3716
+ case 'Some':
3717
+ return 'option';
3718
+ default:
3719
+ return undefined;
3720
+ }
3721
+ }
3722
+ function getCanonicalResultClassFamilyForGenericRelationInfo(info) {
3723
+ const declarations = info.symbol.getDeclarations() ?? [];
3724
+ if (!declarations.some((declaration) => isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
3725
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName))) {
3726
+ return undefined;
3727
+ }
3728
+ return getCanonicalResultClassFamilyForName(info.name);
3729
+ }
3730
+ function getCanonicalResultClassFamilyForIdentity(identity) {
3731
+ const declarations = identity.symbol.getDeclarations() ?? [];
3732
+ if (!declarations.some((declaration) => isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
3733
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName))) {
3734
+ return undefined;
3735
+ }
3736
+ return getCanonicalResultClassFamilyForName(identity.symbol.getName());
3737
+ }
3738
+ function getCanonicalResultClassFamilyForTargetIdentitySet(identitySet) {
3739
+ let family;
3740
+ for (const identity of identitySet.identities) {
3741
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
3742
+ if (!identityFamily) {
3743
+ return undefined;
3744
+ }
3745
+ if (family && family !== identityFamily) {
3746
+ return undefined;
3747
+ }
3748
+ family = identityFamily;
3749
+ }
3750
+ return family;
3751
+ }
3752
+ function getCanonicalResultClassFamilyForType(context, type, visitedTypeIds = new Set()) {
3753
+ const normalizedType = getSafeNonNullableRelationType(context, type);
3754
+ const rawTypeId = normalizedType.id;
3755
+ let visitedTypeId;
3756
+ if (typeof rawTypeId === 'number') {
3757
+ if (visitedTypeIds.has(rawTypeId)) {
3758
+ return undefined;
3759
+ }
3760
+ visitedTypeIds.add(rawTypeId);
3761
+ visitedTypeId = rawTypeId;
3762
+ }
3763
+ try {
3764
+ if ((normalizedType.flags & ts.TypeFlags.Union) !== 0) {
3765
+ let family;
3766
+ let sawConstituent = false;
3767
+ for (const constituentType of normalizedType.types) {
3768
+ const normalizedConstituentType = getSafeNonNullableRelationType(context, constituentType);
3769
+ if ((normalizedConstituentType.flags & ts.TypeFlags.Never) !== 0) {
3770
+ continue;
3771
+ }
3772
+ const constituentFamily = getCanonicalResultClassFamilyForType(context, normalizedConstituentType, visitedTypeIds);
3773
+ if (!constituentFamily) {
3774
+ return undefined;
3775
+ }
3776
+ if (family && family !== constituentFamily) {
3777
+ return undefined;
3778
+ }
3779
+ sawConstituent = true;
3780
+ family = constituentFamily;
3781
+ }
3782
+ return sawConstituent ? family : undefined;
3783
+ }
3784
+ if ((normalizedType.flags & ts.TypeFlags.Intersection) !== 0) {
3785
+ let family;
3786
+ for (const constituentType of normalizedType.types) {
3787
+ const constituentFamily = getCanonicalResultClassFamilyForType(context, constituentType, visitedTypeIds);
3788
+ if (!constituentFamily) {
3789
+ continue;
3790
+ }
3791
+ if (family && family !== constituentFamily) {
3792
+ return undefined;
3793
+ }
3794
+ family = constituentFamily;
3795
+ }
3796
+ return family;
3797
+ }
3798
+ const relationInfo = getGenericRelationTypeInfo(context, normalizedType);
3799
+ const relationFamily = relationInfo
3800
+ ? getCanonicalResultClassFamilyForGenericRelationInfo(relationInfo)
3801
+ : undefined;
3802
+ if (relationFamily) {
3803
+ return relationFamily;
3804
+ }
3805
+ const directIdentity = getDirectClassIdentity(context, normalizedType);
3806
+ const directFamily = directIdentity
3807
+ ? getCanonicalResultClassFamilyForIdentity(directIdentity)
3808
+ : undefined;
3809
+ if (directFamily) {
3810
+ return directFamily;
3811
+ }
3812
+ const identities = collectGenericClassIdentities(context, normalizedType);
3813
+ if (identities.length === 0) {
3814
+ return undefined;
3815
+ }
3816
+ let family;
3817
+ for (const identity of identities) {
3818
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
3819
+ if (!identityFamily) {
3820
+ return undefined;
3821
+ }
3822
+ if (family && family !== identityFamily) {
3823
+ return undefined;
3824
+ }
3825
+ family = identityFamily;
3826
+ }
3827
+ return family;
3828
+ }
3829
+ finally {
3830
+ if (visitedTypeId !== undefined) {
3831
+ visitedTypeIds.delete(visitedTypeId);
3832
+ }
3833
+ }
3834
+ }
3835
+ function sharesCanonicalResultClassFamily(context, sourceType, targetType) {
3836
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3837
+ return sourceFamily !== undefined &&
3838
+ sourceFamily === getCanonicalResultClassFamilyForType(context, targetType);
3839
+ }
3686
3840
  function getGenericParameterNames(symbol, arity) {
3687
3841
  const typeParameters = getSymbolTypeParameterDeclarations(symbol);
3688
3842
  return typeParameters.length === arity
@@ -99,6 +99,8 @@ interface TargetNewtypeIdentitySet {
99
99
  mode: 'intersection' | 'single' | 'union';
100
100
  }
101
101
 
102
+ type CanonicalResultClassFamily = 'option' | 'result';
103
+
102
104
  type NominalIdentityLike = { symbol: ts.Symbol; typeArguments: readonly ts.Type[] };
103
105
  type NominalIdentitySet<TIdentity extends NominalIdentityLike> = {
104
106
  identities: readonly TIdentity[];
@@ -2513,7 +2515,8 @@ function isInstalledSoundStdlibSourceFile(sourceFile: ts.SourceFile): boolean {
2513
2515
  return normalizedFileName.includes('/node_modules/@soundscript/soundscript/') &&
2514
2516
  (
2515
2517
  normalizedFileName.endsWith('.d.ts') ||
2516
- normalizedFileName.endsWith('.sts')
2518
+ normalizedFileName.endsWith('.sts') ||
2519
+ normalizedFileName.endsWith('.sts.ts')
2517
2520
  );
2518
2521
  }
2519
2522
 
@@ -5609,10 +5612,24 @@ function classifyCurrentTypeNodeNominalClassRelation(
5609
5612
  sourceExpression?: ts.Expression,
5610
5613
  sourceTypeNode?: ts.TypeNode,
5611
5614
  ): RelationMismatch | undefined {
5615
+ if (
5616
+ sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
5617
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
5618
+ sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
5619
+ sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)
5620
+ ) {
5621
+ return undefined;
5622
+ }
5623
+
5612
5624
  const targetIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, targetTypeNode);
5613
5625
  if (!targetIdentitySet) {
5614
5626
  return undefined;
5615
5627
  }
5628
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
5629
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
5630
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
5631
+ return undefined;
5632
+ }
5616
5633
 
5617
5634
  const sourceIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, sourceTypeNode) ??
5618
5635
  getDeclaredClassIdentitySetFromExpression(context, sourceExpression);
@@ -6019,6 +6036,12 @@ function classifySourceTypeAgainstTargetClassIdentitySet(
6019
6036
  targetType: ts.Type,
6020
6037
  targetIdentitySet: TargetClassIdentitySet,
6021
6038
  ): RelationMismatch | undefined {
6039
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
6040
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
6041
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
6042
+ return undefined;
6043
+ }
6044
+
6022
6045
  if (targetIdentitySet.mode === 'union') {
6023
6046
  const normalizedSourceType = getSafeNonNullableRelationType(context, sourceType);
6024
6047
  if ((normalizedSourceType.flags & ts.TypeFlags.Never) !== 0) {
@@ -6098,6 +6121,7 @@ function classifyUnsoundNominalClassRelation(
6098
6121
  targetType: ts.Type,
6099
6122
  ): RelationMismatch | undefined {
6100
6123
  if (
6124
+ sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
6101
6125
  sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
6102
6126
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
6103
6127
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)
@@ -6194,6 +6218,7 @@ function classifyUnsoundGenericClassInstanceRelation(
6194
6218
  targetType: ts.Type,
6195
6219
  ): RelationMismatch | undefined {
6196
6220
  if (
6221
+ sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
6197
6222
  sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
6198
6223
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
6199
6224
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)
@@ -6312,6 +6337,187 @@ function sharesEquivalentTargetClassIdentitySets(
6312
6337
  );
6313
6338
  }
6314
6339
 
6340
+ function isTrustedResultStdlibSourceFileName(fileName: string): boolean {
6341
+ return /(?:^|[\\/])(?:index|result)(?:\.sts)?(?:\.d)?\.ts$/.test(fileName);
6342
+ }
6343
+
6344
+ function getCanonicalResultClassFamilyForName(
6345
+ name: string,
6346
+ ): CanonicalResultClassFamily | undefined {
6347
+ switch (name) {
6348
+ case 'Err':
6349
+ case 'Ok':
6350
+ case 'Result':
6351
+ return 'result';
6352
+ case 'None':
6353
+ case 'Option':
6354
+ case 'Some':
6355
+ return 'option';
6356
+ default:
6357
+ return undefined;
6358
+ }
6359
+ }
6360
+
6361
+ function getCanonicalResultClassFamilyForGenericRelationInfo(
6362
+ info: GenericRelationTypeInfo,
6363
+ ): CanonicalResultClassFamily | undefined {
6364
+ const declarations = info.symbol.getDeclarations() ?? [];
6365
+ if (!declarations.some((declaration) =>
6366
+ isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
6367
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName)
6368
+ )) {
6369
+ return undefined;
6370
+ }
6371
+
6372
+ return getCanonicalResultClassFamilyForName(info.name);
6373
+ }
6374
+
6375
+ function getCanonicalResultClassFamilyForIdentity(
6376
+ identity: GenericClassIdentity,
6377
+ ): CanonicalResultClassFamily | undefined {
6378
+ const declarations = identity.symbol.getDeclarations() ?? [];
6379
+ if (!declarations.some((declaration) =>
6380
+ isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
6381
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName)
6382
+ )) {
6383
+ return undefined;
6384
+ }
6385
+
6386
+ return getCanonicalResultClassFamilyForName(identity.symbol.getName());
6387
+ }
6388
+
6389
+ function getCanonicalResultClassFamilyForTargetIdentitySet(
6390
+ identitySet: TargetClassIdentitySet,
6391
+ ): CanonicalResultClassFamily | undefined {
6392
+ let family: CanonicalResultClassFamily | undefined;
6393
+ for (const identity of identitySet.identities) {
6394
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
6395
+ if (!identityFamily) {
6396
+ return undefined;
6397
+ }
6398
+ if (family && family !== identityFamily) {
6399
+ return undefined;
6400
+ }
6401
+ family = identityFamily;
6402
+ }
6403
+
6404
+ return family;
6405
+ }
6406
+
6407
+ function getCanonicalResultClassFamilyForType(
6408
+ context: AnalysisContext,
6409
+ type: ts.Type,
6410
+ visitedTypeIds: Set<number> = new Set(),
6411
+ ): CanonicalResultClassFamily | undefined {
6412
+ const normalizedType = getSafeNonNullableRelationType(context, type);
6413
+ const rawTypeId = (normalizedType as ts.Type & { id?: number }).id;
6414
+ let visitedTypeId: number | undefined;
6415
+ if (typeof rawTypeId === 'number') {
6416
+ if (visitedTypeIds.has(rawTypeId)) {
6417
+ return undefined;
6418
+ }
6419
+ visitedTypeIds.add(rawTypeId);
6420
+ visitedTypeId = rawTypeId;
6421
+ }
6422
+
6423
+ try {
6424
+ if ((normalizedType.flags & ts.TypeFlags.Union) !== 0) {
6425
+ let family: CanonicalResultClassFamily | undefined;
6426
+ let sawConstituent = false;
6427
+ for (const constituentType of (normalizedType as ts.UnionType).types) {
6428
+ const normalizedConstituentType = getSafeNonNullableRelationType(context, constituentType);
6429
+ if ((normalizedConstituentType.flags & ts.TypeFlags.Never) !== 0) {
6430
+ continue;
6431
+ }
6432
+ const constituentFamily = getCanonicalResultClassFamilyForType(
6433
+ context,
6434
+ normalizedConstituentType,
6435
+ visitedTypeIds,
6436
+ );
6437
+ if (!constituentFamily) {
6438
+ return undefined;
6439
+ }
6440
+ if (family && family !== constituentFamily) {
6441
+ return undefined;
6442
+ }
6443
+ sawConstituent = true;
6444
+ family = constituentFamily;
6445
+ }
6446
+
6447
+ return sawConstituent ? family : undefined;
6448
+ }
6449
+
6450
+ if ((normalizedType.flags & ts.TypeFlags.Intersection) !== 0) {
6451
+ let family: CanonicalResultClassFamily | undefined;
6452
+ for (const constituentType of (normalizedType as ts.IntersectionType).types) {
6453
+ const constituentFamily = getCanonicalResultClassFamilyForType(
6454
+ context,
6455
+ constituentType,
6456
+ visitedTypeIds,
6457
+ );
6458
+ if (!constituentFamily) {
6459
+ continue;
6460
+ }
6461
+ if (family && family !== constituentFamily) {
6462
+ return undefined;
6463
+ }
6464
+ family = constituentFamily;
6465
+ }
6466
+
6467
+ return family;
6468
+ }
6469
+
6470
+ const relationInfo = getGenericRelationTypeInfo(context, normalizedType);
6471
+ const relationFamily = relationInfo
6472
+ ? getCanonicalResultClassFamilyForGenericRelationInfo(relationInfo)
6473
+ : undefined;
6474
+ if (relationFamily) {
6475
+ return relationFamily;
6476
+ }
6477
+
6478
+ const directIdentity = getDirectClassIdentity(context, normalizedType);
6479
+ const directFamily = directIdentity
6480
+ ? getCanonicalResultClassFamilyForIdentity(directIdentity)
6481
+ : undefined;
6482
+ if (directFamily) {
6483
+ return directFamily;
6484
+ }
6485
+
6486
+ const identities = collectGenericClassIdentities(context, normalizedType);
6487
+ if (identities.length === 0) {
6488
+ return undefined;
6489
+ }
6490
+
6491
+ let family: CanonicalResultClassFamily | undefined;
6492
+ for (const identity of identities) {
6493
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
6494
+ if (!identityFamily) {
6495
+ return undefined;
6496
+ }
6497
+ if (family && family !== identityFamily) {
6498
+ return undefined;
6499
+ }
6500
+ family = identityFamily;
6501
+ }
6502
+
6503
+ return family;
6504
+ } finally {
6505
+ if (visitedTypeId !== undefined) {
6506
+ visitedTypeIds.delete(visitedTypeId);
6507
+ }
6508
+ }
6509
+ }
6510
+
6511
+ function sharesCanonicalResultClassFamily(
6512
+ context: AnalysisContext,
6513
+ sourceType: ts.Type,
6514
+ targetType: ts.Type,
6515
+ ): boolean {
6516
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
6517
+ return sourceFamily !== undefined &&
6518
+ sourceFamily === getCanonicalResultClassFamilyForType(context, targetType);
6519
+ }
6520
+
6315
6521
  function getGenericParameterNames(
6316
6522
  symbol: ts.Symbol,
6317
6523
  arity: number,
@@ -11,7 +11,7 @@ import { createTempDirectory, fileExistsSync, makeDirectory, readStdinText, remo
11
11
  import { materializeRuntimeGraph, } from './runtime/materialize.js';
12
12
  import { runProgram } from './run_program.js';
13
13
  import { projectEditorFile } from './editor_projection.js';
14
- export const VERSION = '0.1.15';
14
+ export const VERSION = '0.1.16';
15
15
  const FINDINGS_EXIT_CODE = 1;
16
16
  const CLI_FAILURE_EXIT_CODE = 2;
17
17
  function createCliDiagnostic(code, message, filePath, details) {
@@ -59,7 +59,7 @@ import {
59
59
  import { runProgram, type RunProgramOptions, type RunProgramResult } from './run_program.ts';
60
60
  import { projectEditorFile } from './editor_projection.ts';
61
61
 
62
- export const VERSION = '0.1.15';
62
+ export const VERSION = '0.1.16';
63
63
  const FINDINGS_EXIT_CODE = 1;
64
64
  const CLI_FAILURE_EXIT_CODE = 2;
65
65
 
@@ -8,11 +8,11 @@ export class DecodeFailure extends Failure {
8
8
  readonly path: DecodePath;
9
9
  constructor(
10
10
  message?: string,
11
- options?: {
11
+ options?: Readonly<{
12
12
  cause?: unknown;
13
13
  path?: DecodePath;
14
14
  trace?: readonly ErrorFrame[];
15
- },
15
+ }>,
16
16
  );
17
17
  at(segment: DecodePathSegment): this;
18
18
  }
@@ -9,11 +9,11 @@ export class DecodeFailure extends Failure {
9
9
 
10
10
  constructor(
11
11
  message = 'Failed to decode value.',
12
- options: {
12
+ options: Readonly<{
13
13
  cause?: unknown;
14
14
  path?: DecodePath;
15
15
  trace?: readonly ErrorFrame[];
16
- } = {},
16
+ }> = {},
17
17
  ) {
18
18
  super(message, {
19
19
  ...(options.cause === undefined ? {} : { cause: options.cause }),
@@ -9,11 +9,11 @@ export class DecodeFailure extends Failure {
9
9
 
10
10
  constructor(
11
11
  message = 'Failed to decode value.',
12
- options: {
12
+ options: Readonly<{
13
13
  cause?: unknown;
14
14
  path?: DecodePath;
15
15
  trace?: readonly ErrorFrame[];
16
- } = {},
16
+ }> = {},
17
17
  ) {
18
18
  super(message, {
19
19
  ...(options.cause === undefined ? {} : { cause: options.cause }),