Socket
Socket
Sign inDemoInstall

staack

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

staack - npm Package Compare versions

Comparing version 1.0.9 to 2.0.0

72

dist/mod.d.ts
declare const INTERNAL: unique symbol;
declare const MIID_DEBUG: unique symbol;
declare const PROVIDER: unique symbol;
declare const PARENT: unique symbol;
interface KeyConsumer<T, HasDefault extends boolean = boolean> {

@@ -32,22 +34,57 @@ readonly name: string;

}): Key<T, false>;
type StaackInternal<Parent extends Staack = Staack> = {
readonly provider: KeyProvider<any>;
readonly parent: Parent;
};
declare class MissingContextError extends Error {
context: KeyConsumer<any>;
keyConsumer: KeyConsumer<any>;
readonly help?: string;
constructor(context: KeyConsumer<any>);
constructor(keyConsumer: KeyConsumer<any>);
}
declare class Staack {
type StaackCoreTuple = [parent: StaackCore, provider: KeyProvider<any>];
type StaackCoreValue = StaackCore | null;
declare class StaackCore {
static readonly MissingContextError: typeof MissingContextError;
static applyKeys<T extends Staack>(instance: T, keys: Array<KeyProvider<any>>, instantiate: (internal: StaackInternal<T>) => T): T;
private readonly [INTERNAL];
constructor(internal?: StaackInternal<Staack> | null);
protected readInternal(consumer: KeyConsumer<any, any>): {
private readonly [PARENT];
private readonly [PROVIDER];
protected constructor(provider: KeyProvider<any>, parent?: StaackCoreValue);
/**
* READ Functions
*/
static findFirstMatch(staack: StaackCoreValue, consumer: KeyConsumer<any, any>): {
found: boolean;
value: any;
};
has(ctx: KeyConsumer<any, any>): boolean;
get<T, HasDefault extends boolean>(ctx: KeyConsumer<T, HasDefault>): HasDefault extends true ? T : T | null;
static has(staack: StaackCoreValue, consumer: KeyConsumer<any, any>): boolean;
static get<T, HasDefault extends boolean>(staack: StaackCoreValue, consumer: KeyConsumer<T, HasDefault>): HasDefault extends true ? T : T | null;
static getAll<T>(staack: StaackCoreValue, consumer: KeyConsumer<T>): IterableIterator<T>;
static getOrFail<T>(staack: StaackCoreValue, consumer: KeyConsumer<T>): T;
static extract(staack: StaackCoreValue): IterableIterator<StaackCoreTuple>;
/**
* WRITE Functions
*/
static with(staack: StaackCoreValue, ...keys: readonly KeyProvider<any>[]): StaackCoreValue;
/**
* Merge two StaackCore instances into one.
* [...left, ...right]
* If left is empty, return right.
* If right is empty, return left.
*/
static merge(left: StaackCoreValue, right: StaackCoreValue): StaackCoreValue;
/**
* Remove duplicated providers from the StaackCore.
*/
static dedupe(staack: StaackCoreValue): StaackCoreValue;
static debug(staack: StaackCoreValue): Array<{
value: any;
ctxId: string;
}>;
}
declare class Staack {
static readonly MissingContextError: typeof MissingContextError;
private readonly [INTERNAL];
protected constructor(core?: StaackCoreValue);
static create(...keys: Array<KeyProvider<any>>): Staack;
has(consumer: KeyConsumer<any, any>): boolean;
get<T, HasDefault extends boolean>(consumer: KeyConsumer<T, HasDefault>): HasDefault extends true ? T : T | null;
getAll<T>(consumer: KeyConsumer<T>): IterableIterator<T>;
getOrFail<T>(consumer: KeyConsumer<T>): T;

@@ -58,5 +95,8 @@ debug(): Array<{

}>;
with(...keys: Array<KeyProvider<any>>): Staack;
protected instantiate(staackCore: StaackCoreValue): this;
with(...keys: Array<KeyProvider<any>>): this;
merge(other: Staack): this;
dedupe(): this;
}
export { INTERNAL, Key, KeyConsumer, KeyProvider, KeyProviderFn, MIID_DEBUG, MissingContextError, Staack, StaackInternal, createKey };
export { Key, KeyConsumer, KeyProvider, KeyProviderFn, MissingContextError, Staack, StaackCore, StaackCoreTuple, StaackCoreValue, createKey };

@@ -28,11 +28,16 @@ "use strict";

__export(mod_exports, {
INTERNAL: () => INTERNAL,
MIID_DEBUG: () => MIID_DEBUG,
MissingContextError: () => MissingContextError,
Staack: () => Staack,
StaackCore: () => StaackCore,
createKey: () => createKey
});
module.exports = __toCommonJS(mod_exports);
var INTERNAL = Symbol.for("MIID_INTERNAL");
var MIID_DEBUG = Symbol.for("MIID_DEBUG");
// src/constants.ts
var INTERNAL = Symbol.for("INTERNAL");
var PROVIDER = Symbol.for("PROVIDER");
var PARENT = Symbol.for("PARENT");
var DEBUG = Symbol.for("DEBUG");
// src/Key.ts
function createKey(options) {

@@ -53,48 +58,47 @@ const { help, name } = options;

}
// src/MissingContextError.ts
var MissingContextError = class extends Error {
constructor(context) {
super(`Cannot find context ${context.name}`);
this.context = context;
constructor(keyConsumer) {
super(`Cannot find context ${keyConsumer.name}`);
this.keyConsumer = keyConsumer;
Object.setPrototypeOf(this, new.target.prototype);
this.help = context[INTERNAL].help;
this.help = keyConsumer[INTERNAL].help;
}
help;
};
var _Staack = class {
static applyKeys(instance, keys, instantiate) {
if (keys.length === 0) {
return instance;
}
return [...keys].reverse().reduce((parent, provider) => {
return instantiate({ parent, provider });
}, instance);
// src/StaackCore.ts
var _StaackCore = class {
[PARENT];
// Null if root
[PROVIDER];
constructor(provider, parent = null) {
this[PARENT] = parent;
this[PROVIDER] = provider;
}
[INTERNAL];
constructor(internal = null) {
this[INTERNAL] = internal;
}
readInternal(consumer) {
const internal = this[INTERNAL];
if (internal === null) {
return {
found: false,
value: null
};
/**
* READ Functions
*/
static findFirstMatch(staack, consumer) {
if (staack === null) {
return { found: false, value: null };
}
if (internal.provider[INTERNAL].consumer === consumer) {
const provider = staack[PROVIDER];
if (provider[INTERNAL].consumer === consumer) {
return {
found: true,
value: internal.provider[INTERNAL].value
value: provider[INTERNAL].value
};
}
return internal.parent.readInternal(consumer);
return _StaackCore.findFirstMatch(staack[PARENT], consumer);
}
has(ctx) {
return this.readInternal(ctx).found;
static has(staack, consumer) {
return _StaackCore.findFirstMatch(staack, consumer).found;
}
get(ctx) {
const res = this.readInternal(ctx);
static get(staack, consumer) {
const res = _StaackCore.findFirstMatch(staack, consumer);
if (res.found === false) {
if (ctx[INTERNAL].hasDefault) {
return ctx[INTERNAL].defaultValue;
if (consumer[INTERNAL].hasDefault) {
return consumer[INTERNAL].defaultValue;
}

@@ -105,4 +109,22 @@ return null;

}
getOrFail(consumer) {
const res = this.readInternal(consumer);
static getAll(staack, consumer) {
let current = staack;
return {
next() {
while (current) {
const provider = current[PROVIDER];
current = current[PARENT];
if (provider[INTERNAL].consumer === consumer) {
return { value: provider[INTERNAL].value, done: false };
}
}
return { value: void 0, done: true };
},
[Symbol.iterator]() {
return this;
}
};
}
static getOrFail(staack, consumer) {
const res = _StaackCore.findFirstMatch(staack, consumer);
if (res.found === false) {

@@ -116,33 +138,148 @@ if (consumer[INTERNAL].hasDefault) {

}
debug() {
static extract(staack) {
let current = staack;
return {
next() {
if (current) {
const parent = current;
const provider = current[PROVIDER];
current = current[PARENT];
return { value: [parent, provider], done: false };
}
return { value: void 0, done: true };
},
[Symbol.iterator]() {
return this;
}
};
}
/**
* WRITE Functions
*/
static with(staack, ...keys) {
if (keys.length === 0) {
return staack;
}
return [...keys].reduce((parent, provider) => {
return new _StaackCore(provider, parent);
}, staack);
}
/**
* Merge two StaackCore instances into one.
* [...left, ...right]
* If left is empty, return right.
* If right is empty, return left.
*/
static merge(left, right) {
if (left === null || right === null) {
return left ?? right ?? null;
}
const rightExtracted = Array.from(_StaackCore.extract(right), ([, provider]) => provider).reverse();
return _StaackCore.with(left, ...rightExtracted);
}
/**
* Remove duplicated providers from the StaackCore.
*/
static dedupe(staack) {
if (staack === null) {
return null;
}
const seenKeys = /* @__PURE__ */ new Set();
const queue = [];
let base = staack;
let baseQueue = [];
for (const [item, provider] of _StaackCore.extract(staack)) {
if (seenKeys.has(provider[INTERNAL].consumer)) {
base = item[PARENT];
queue.push(...baseQueue);
baseQueue = [];
continue;
}
seenKeys.add(provider[INTERNAL].consumer);
baseQueue.push(provider);
}
if (base === staack) {
return staack;
}
queue.push(...baseQueue);
return _StaackCore.with(base, ...queue.reverse());
}
static debug(staack) {
const world = globalThis;
const idMap = world[MIID_DEBUG] || /* @__PURE__ */ new Map();
if (!world[MIID_DEBUG]) {
world[MIID_DEBUG] = idMap;
}
const idMap = world[DEBUG] || (world[DEBUG] = /* @__PURE__ */ new Map());
const result = [];
const traverse = (staack) => {
const internal = staack[INTERNAL];
if (internal === null) {
traverse(staack);
return result;
function traverse(staack2) {
if (staack2 === null) {
return;
}
let ctxId = idMap.get(internal.provider[INTERNAL].consumer);
const provider = staack2[PROVIDER];
let ctxId = idMap.get(provider[INTERNAL].consumer);
if (ctxId === void 0) {
ctxId = Math.random().toString(36).substring(7);
idMap.set(internal.provider[INTERNAL].consumer, ctxId);
idMap.set(provider[INTERNAL].consumer, ctxId);
}
result.push({
ctxId,
value: internal.provider[INTERNAL].value
value: provider[INTERNAL].value
});
if (internal.parent) {
traverse(internal.parent);
}
};
traverse(this);
return result;
traverse(staack2[PARENT]);
}
}
};
var StaackCore = _StaackCore;
__publicField(StaackCore, "MissingContextError", MissingContextError);
// src/Staack.ts
var _Staack = class {
[INTERNAL];
constructor(core = null) {
this[INTERNAL] = core;
}
static create(...keys) {
return new _Staack(StaackCore.with(null, ...keys));
}
has(consumer) {
return StaackCore.has(this[INTERNAL], consumer);
}
get(consumer) {
return StaackCore.get(this[INTERNAL], consumer);
}
getAll(consumer) {
return StaackCore.getAll(this[INTERNAL], consumer);
}
getOrFail(consumer) {
return StaackCore.getOrFail(this[INTERNAL], consumer);
}
debug() {
return StaackCore.debug(this[INTERNAL]);
}
instantiate(staackCore) {
if (this.constructor !== _Staack) {
throw new Error("Cannot instantiate a Staack subclass, you need to override instantiate()");
}
return new _Staack(staackCore);
}
with(...keys) {
return _Staack.applyKeys(this, keys, (internal) => new _Staack(internal));
const nextCore = StaackCore.with(this[INTERNAL], ...keys);
if (nextCore === this[INTERNAL]) {
return this;
}
return this.instantiate(nextCore);
}
merge(other) {
const nextCore = StaackCore.merge(this[INTERNAL], other[INTERNAL]);
if (nextCore === this[INTERNAL]) {
return this;
}
return this.instantiate(nextCore);
}
dedupe() {
const nextCore = StaackCore.dedupe(this[INTERNAL]);
if (nextCore === this[INTERNAL]) {
return this;
}
return this.instantiate(nextCore);
}
};

@@ -153,7 +290,6 @@ var Staack = _Staack;

0 && (module.exports = {
INTERNAL,
MIID_DEBUG,
MissingContextError,
Staack,
StaackCore,
createKey
});
{
"name": "staack",
"version": "1.0.9",
"version": "2.0.0",
"description": "A library to create type-safe opaque stacks",

@@ -5,0 +5,0 @@ "keywords": [

@@ -8,3 +8,13 @@ # 🏯 Staack

```ts
// TODO
// 1. Create a key with a name and a type
const NumKey = createKey<number>({ name: 'Num' });
// 2. Create a stack
const stack = Staack.create();
// 3. Add a value to the stack using the key (Staack is immutable, it returns a new instance)
const stack2 = stack.with(NumKey.Provider(42));
// 4. Get the value from the stack using the key
expect(stack2.get(NumKey.Consumer)).toBe(42);
```

@@ -26,32 +36,16 @@

class CustomStaack extends Staack {
// You need to override the `with` method to return a new instance of your CustomStaack
with(...keys: Array<KeyProvider<any>>): CustomStaack {
// Use the static `applyKeys` method to apply keys to the current instance
return Staack.applyKeys<CustomStaack>(this, keys, (internal) => new CustomStaack(internal));
// Override the `create` method to return a new instance of your CustomStack
static create(...keys: KeyProvider<any, boolean>[]): CustomStaack {
return new CustomStaack().with(...keys);
}
}
const custom = new CustomStaack();
expect(custom instanceof CustomStaack).toBe(true);
expect(custom instanceof Staack).toBe(true);
```
If you want to pass custom arguments to yout CustomStaack:
```ts
class ParamsStaack extends Staack {
// You can pass your own parameters to the constructor
constructor(public readonly param: string, internal: StaackInternal<ParamsStaack> | null = null) {
super(internal);
// You need to override the `instantiate` method to return a new instance of your CustomStack
protected instantiate(staackCore: StaackCoreValue): this {
return new CustomStaack(staackCore) as any;
}
with(...keys: Array<KeyProvider<any>>): ParamsStaack {
return Staack.applyKeys<ParamsStaack>(this, keys, (internal) => new ParamsStaack(this.param, internal));
}
}
const custom = new ParamsStaack('some value');
expect(custom.param).toBe('some value');
expect(custom instanceof ParamsStaack).toBe(true);
const custom = CustomStaack.create();
expect(custom instanceof CustomStaack).toBe(true);
expect(custom instanceof Staack).toBe(true);
```

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