-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
172 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
"@zazuko/env": major | ||
"@zazuko/env-node": major | ||
--- | ||
|
||
Change the method of creating derived environments: | ||
|
||
1. The additional factories have been removed from the `create` function. | ||
2. To create a derived environment, use the constructor overload which takes a parent environment as the second argument in addition to the array of additional factories. | ||
|
||
For example, | ||
|
||
```js | ||
import env from '@zazuko/env'; | ||
import Environment from '@zazuko/env/Environment.js'; | ||
import MyFactory from './my-factory.js'; | ||
|
||
const myEnv = Environment([MyFactory], env); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Environment, FactoryConstructor } from '@rdfjs/environment/Environment.js' | ||
import { DerivedEnvironment } from './lib/extend.js' | ||
|
||
type Narrow<T> = | ||
| (T extends infer U ? U : never) | ||
| Extract<T, number | string | boolean | bigint | symbol | null | undefined | []> | ||
| ([T] extends [[]] ? [] : { [K in keyof T]: Narrow<T[K]> }); | ||
|
||
type ReturnFactory<C> = C extends FactoryConstructor<infer X> ? X : C; | ||
type Distribute<U> = U extends any ? ReturnFactory<U> : never; | ||
|
||
interface EnvironmentCtor { | ||
new<F extends ReadonlyArray<FactoryConstructor<any>>>( | ||
factories: Narrow<F>, | ||
options?: { bind: boolean }, | ||
): Environment<Distribute<F[number]>> | ||
|
||
new<F extends ReadonlyArray<FactoryConstructor<any>>, E extends Environment<any>>( | ||
factories: Narrow<F>, | ||
parent?: E, | ||
options?: { bind: boolean }, | ||
): DerivedEnvironment<E, Environment<Distribute<F[number]>>> | ||
} | ||
|
||
declare const environment: EnvironmentCtor | ||
|
||
export default environment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { extend } from './lib/extend.js' | ||
|
||
export default class Environment { | ||
constructor(factories, parent, { bind = false } = {}) { | ||
this._parent = parent | ||
this._factories = factories | ||
|
||
const extended = parent ? extend(parent, this) : this | ||
|
||
for (const factory of this._factories) { | ||
if (typeof factory.prototype.init === 'function') { | ||
factory.prototype.init.call(extended) | ||
} | ||
|
||
for (const method of factory.exports || []) { | ||
if (bind) { | ||
this[method] = factory.prototype[method].bind(extended) | ||
} else { | ||
this[method] = factory.prototype[method] | ||
} | ||
} | ||
} | ||
|
||
return extended | ||
} | ||
|
||
clone() { | ||
const env = new Environment(this._factories, this._parent) | ||
|
||
for (const factory of env._factories) { | ||
if (typeof factory.prototype.clone === 'function') { | ||
factory.prototype.clone.call(env, this) | ||
} | ||
} | ||
|
||
return env | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import type { Environment } from '@rdfjs/environment/Environment.js' | ||
|
||
type Factories<E> = E extends Environment<infer F> ? F : never; | ||
type Distribute<U> = U extends any ? Factories<U> : never; | ||
|
||
type CombinedEnvironment<E extends ReadonlyArray<Environment<any>>> = Environment<Distribute<E[number]>> | ||
export type DerivedEnvironment<Env extends Environment<unknown>, Ex extends Environment<unknown>> = CombinedEnvironment<[Env, Ex]> | ||
|
||
export function extend<E extends Environment<any>, P extends Environment<any>>(self: E, parent: P) { | ||
return new Proxy([self, parent], { | ||
get(target, prop) { | ||
const value = target.find(env => prop in env) | ||
if (value) { | ||
return value[prop as keyof E] | ||
} | ||
}, | ||
set(target, prop, value) { | ||
target[0][prop as keyof E] = value | ||
|
||
return true | ||
}, | ||
has(target, prop) { | ||
return target.some(env => prop in env) | ||
}, | ||
}) as any as DerivedEnvironment<P, E> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import DataFactory from '@rdfjs/data-model/Factory.js' | ||
import DatasetFactory from '@rdfjs/dataset/Factory.js' | ||
import { describe } from 'mocha' | ||
import { expect } from 'chai' | ||
import { schema } from '@tpluscode/rdf-ns-builders' | ||
import Environment from '../Environment.js' | ||
import { TestFactory } from './TestFactory.js' | ||
|
||
describe('Environment', () => { | ||
context('with parent', () => { | ||
it('merges all factories', () => { | ||
// given | ||
const dataEnv = new Environment([DataFactory]) | ||
|
||
// when | ||
const env = new Environment([DatasetFactory], dataEnv) | ||
|
||
// then | ||
expect(env).to.have.property('dataset') | ||
expect(env).to.have.property('namedNode') | ||
expect(env.namedNode('http://schema.org/Person')).to.deep.eq(schema.Person) | ||
}) | ||
|
||
it('merge multiple levels', () => { | ||
// given | ||
const dataEnv = new Environment([DataFactory]) | ||
const datasetEnv = new Environment([DatasetFactory], dataEnv) | ||
|
||
// when | ||
const env = new Environment([TestFactory], datasetEnv) | ||
|
||
// then | ||
const test = env.test() | ||
expect(test.size).to.eq(1) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Environment } from '@rdfjs/environment/Environment.js' | ||
import DataFactory from '@rdfjs/data-model/Factory.js' | ||
import DatasetFactory from '@rdfjs/dataset/Factory.js' | ||
|
||
export class TestFactory { | ||
test(this: Environment<DataFactory | DatasetFactory>) { | ||
return this.dataset([ | ||
this.quad(this.blankNode(), this.namedNode('http://example.org/'), this.literal('test')), | ||
]) | ||
} | ||
|
||
static get exports() { | ||
return ['test'] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters