Socket
Socket
Sign inDemoInstall

@arktype/util

Package Overview
Dependencies
Maintainers
1
Versions
78
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@arktype/util - npm Package Compare versions

Comparing version 0.0.13 to 0.0.14

3

__tests__/traits.test.ts
import { attest } from "@arktype/attest"
import { Trait, compose } from "../trait2.js"
import { Trait, compose } from "@arktype/util"

@@ -134,3 +134,2 @@ export class Describable extends Trait<{ writeDefaultDescription(): string }> {

class B extends Trait<{ b(): number }> {}
// @ts-expect-error

@@ -137,0 +136,0 @@ attest(class C extends compose(A, B)({}) {}).type.errors(

@@ -6,2 +6,3 @@ export type pathToString<segments extends string[], delimiter extends string = "/"> = segments extends [] ? "/" : join<segments, delimiter>;

export declare const intersectUniqueLists: <item>(l: readonly item[], r: readonly item[]) => item[];
export type filter<t extends readonly unknown[], constraint, result extends unknown[] = []> = t extends readonly [infer head, ...infer tail] ? filter<tail, constraint, head extends constraint ? [...result, head] : result> : result;
export type List<t = unknown> = readonly t[];

@@ -8,0 +9,0 @@ export type listable<t> = t | readonly t[];

@@ -68,3 +68,3 @@ import type { Fn } from "./functions.js";

}
declare const NoopBase: new <t extends object>() => t;
export declare const NoopBase: new <t extends object>() => t;
/** @ts-expect-error **/

@@ -71,0 +71,0 @@ export declare class CastableBase<t extends object> extends NoopBase<t> {

@@ -13,3 +13,3 @@ export const entriesOf = (o) => Object.entries(o);

}
const NoopBase = class {
export const NoopBase = class {
};

@@ -16,0 +16,0 @@ /** @ts-expect-error **/

@@ -0,23 +1,54 @@

import type { conform, evaluate } from "./generics.js";
import type { intersectParameters } from "./intersections.js";
import { type Constructor } from "./objectKinds.js";
import { ShallowClone } from "./records.js";
export type TraitComposition = <traits extends readonly Constructor[]>(...traits: traits) => compose<traits>;
import { NoopBase, type optionalizeKeys } from "./records.js";
export type TraitComposition = <traits extends readonly TraitConstructor[]>(...traits: traits) => TraitImplementation<traits, compose<traits>>;
type TraitImplementation<traits extends readonly TraitConstructor[], composed extends ComposedTraits> = <implementation>(implementation: conform<implementation, baseImplementationOf<composed>> & ThisType<implementation & composed["implemented"]>, ...disambiguation: baseDisambiguationOf<traits, implementation, composed> extends infer disambiguation ? {} extends disambiguation ? [] : [disambiguation] : never) => TraitsBase<composed, implementation>;
type TraitsBase<composed extends ComposedTraits, implementation> = composed["statics"] & (new (...args: composed["params"]) => evaluate<intersectImplementations<implementation, composed["implemented"]>>);
type optionalizeSatisfied<base> = optionalizeKeys<base, {
[k in keyof base]: undefined extends base[k] ? k : never;
}[keyof base]>;
type baseImplementationOf<composed extends ComposedTraits> = optionalizeSatisfied<{
[k in keyof composed["abstracted"]]: k extends keyof composed["implemented"] ? composed["implemented"][k] extends composed["abstracted"][k] ? composed["implemented"][k] | undefined : composed["implemented"][k] : composed["abstracted"][k];
}>;
type omitUnambiguous<base> = Omit<base, {
[k in keyof base]: undefined extends base[k] ? k : never;
}[keyof base]>;
type baseDisambiguationOf<traits extends readonly TraitConstructor[], implementation, composed extends ComposedTraits> = omitUnambiguous<{
[k in keyof composed["implemented"]]: k extends keyof implementation ? undefined : k extends keyof Trait ? undefined : traitsImplementingKey<traits, k> extends infer implementations extends TraitConstructor[] ? implementations["length"] extends 1 ? undefined : implementations[number] : never;
}>;
type traitsImplementingKey<traits extends readonly unknown[], k, result extends unknown[] = []> = traits extends readonly [
TraitConstructor<any[], infer instance, infer abstracts>,
...infer tail
] ? traitsImplementingKey<tail, k, k extends Exclude<keyof instance, keyof abstracts> ? [...result, traits[0]] : result> : result;
export declare const hasTrait: (traitClass: Constructor) => (o: unknown) => boolean;
export declare abstract class Trait {
export declare abstract class Trait<abstracted extends object = {}, implemented extends object = {}> extends NoopBase<abstracted & implemented> {
$abstracted: abstracted;
static get [Symbol.hasInstance](): (o: unknown) => boolean;
traitsOf(): readonly Function[];
traitsOf(): readonly TraitConstructor[];
}
export declare abstract class DynamicTrait<t extends object> extends ShallowClone<t> {
static get [Symbol.hasInstance](): (o: unknown) => boolean;
traitsOf(): readonly Function[];
}
export declare const compose: TraitComposition;
export type compose<traits extends readonly Constructor[]> = composeRecurse<traits, [
], {}, {}>;
export type composeRecurse<traits extends readonly unknown[], parameters extends readonly unknown[], statics extends {}, instance extends {}> = traits extends readonly [
abstract new (...args: infer nextArgs) => infer nextInstance,
export type TraitConstructor<params extends readonly unknown[] = any[], instance = {}, abstracted = {}, statics = {}> = statics & (new (...args: params) => {
$abstracted: abstracted;
} & instance);
export type ComposedTraits = {
params: readonly unknown[];
implemented: unknown;
abstracted: unknown;
statics: unknown;
};
export type compose<traits extends readonly TraitConstructor[]> = composeRecurse<traits, [], {}, {}, {}>;
type intersectImplementations<l, r> = {
[k in keyof l]: k extends keyof r ? l[k] extends (...args: infer lArgs) => infer lReturn ? r[k] extends (...args: infer rArgs) => infer rReturn ? (...args: intersectParameters<lArgs, rArgs>) => lReturn & rReturn : l[k] & r[k] : l[k] & r[k] : l[k];
} & Omit<r, keyof l>;
type composeRecurse<traits extends readonly unknown[], params extends readonly unknown[], implemented, abstracted, statics> = traits extends readonly [
TraitConstructor<infer nextParams, infer nextInstance, infer nextAbstracted, infer nextStatics>,
...infer tail
] ? composeRecurse<tail, intersectParameters<parameters, nextArgs>, statics & {
[k in keyof traits[0]]: traits[0][k];
}, instance & nextInstance> : statics & (abstract new (...args: parameters) => instance);
] ? composeRecurse<tail, intersectParameters<params, nextParams>, intersectImplementations<implemented, Omit<nextInstance, keyof nextAbstracted>>, intersectImplementations<abstracted, nextAbstracted>, intersectImplementations<statics, nextStatics>> : {
params: params;
implemented: evaluate<implemented>;
abstracted: evaluate<abstracted>;
statics: evaluate<Omit<statics, keyof typeof Trait>>;
};
export {};
//# sourceMappingURL=traits.d.ts.map
import { hasDomain } from "./domain.js";
import { ancestorsOf } from "./objectKinds.js";
import { ShallowClone } from "./records.js";
import { NoopBase } from "./records.js";
// even though the value we attach will be identical, we use this so classes

@@ -18,3 +18,4 @@ // won't be treated as instanceof a Trait

};
export class Trait {
// @ts-expect-error allow abstract property access
export class Trait extends NoopBase {
static get [Symbol.hasInstance]() {

@@ -29,14 +30,3 @@ return hasTrait(this);

}
// @ts-expect-error see ShallowClone
export class DynamicTrait extends ShallowClone {
static get [Symbol.hasInstance]() {
return hasTrait(this);
}
traitsOf() {
return implementedTraits in this.constructor
? this.constructor[implementedTraits]
: [];
}
}
const collectPrototypeDescriptors = (trait) => {
const collectPrototypeDescriptors = (trait, disambiguation) => {
let proto = trait.prototype;

@@ -49,11 +39,11 @@ let result = {};

} while (proto !== Object.prototype && proto !== null);
for (const k in disambiguation) {
if (disambiguation[k] !== trait) {
// remove keys disambiguated to resolve to other traits
delete result[k];
}
}
return result;
};
export const compose = ((...traits) => {
if (traits.length === 0) {
return Object;
}
if (traits.length === 1) {
return traits[0];
}
export const compose = ((...traits) => (implementation, disambiguation = {}) => {
const base = function (...args) {

@@ -70,3 +60,3 @@ for (const trait of traits) {

// flatten and copy prototype
Object.defineProperties(base.prototype, collectPrototypeDescriptors(trait));
Object.defineProperties(base.prototype, collectPrototypeDescriptors(trait, disambiguation));
if (implementedTraits in trait) {

@@ -88,4 +78,6 @@ // add any ancestor traits from which the current trait was composed

});
// copy implementation last since it overrides traits
Object.defineProperties(base.prototype, Object.getOwnPropertyDescriptors(implementation));
return base;
});
//# sourceMappingURL=traits.js.map
{
"name": "@arktype/util",
"version": "0.0.13",
"version": "0.0.14",
"author": {

@@ -5,0 +5,0 @@ "name": "David Blass",

import { hasDomain } from "./domain.js"
import type { conform, evaluate } from "./generics.js"
import type { intersectParameters } from "./intersections.js"
import type { filter } from "./lists.js"
import { ancestorsOf, type Constructor } from "./objectKinds.js"

@@ -71,6 +70,4 @@ import { NoopBase, type optionalizeKeys } from "./records.js"

? undefined
: filter<
traits,
TraitConstructor<any[], { [_ in k]: unknown }, { [_ in k]?: never }>
> extends infer implementations extends TraitConstructor[]
: traitsImplementingKey<traits, k> extends infer implementations extends
TraitConstructor[]
? implementations["length"] extends 1

@@ -82,2 +79,19 @@ ? undefined

type traitsImplementingKey<
traits extends readonly unknown[],
k,
result extends unknown[] = []
> = traits extends readonly [
TraitConstructor<any[], infer instance, infer abstracts>,
...infer tail
]
? traitsImplementingKey<
tail,
k,
k extends Exclude<keyof instance, keyof abstracts>
? [...result, traits[0]]
: result
>
: result
// even though the value we attach will be identical, we use this so classes

@@ -184,3 +198,3 @@ // won't be treated as instanceof a Trait

type TraitConstructor<
export type TraitConstructor<
params extends readonly unknown[] = any[],

@@ -187,0 +201,0 @@ instance = {},

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc