Socket
Socket
Sign inDemoInstall

@loopback/context

Package Overview
Dependencies
Maintainers
7
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@loopback/context - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

12

CHANGELOG.md

@@ -6,2 +6,14 @@ # Change Log

# [3.2.0](https://github.com/strongloop/loopback-next/compare/@loopback/context@3.1.0...@loopback/context@3.2.0) (2020-03-24)
### Features
* **context:** emit bind/unbind events on ContextView ([65e3d38](https://github.com/strongloop/loopback-next/commit/65e3d38a34b351929ba422de667bc236e9619ebe))
* **context:** improve context view for bind/unbind events ([6a5f90a](https://github.com/strongloop/loopback-next/commit/6a5f90aadb5f5ba213f2da7ea7843f488a09f95d))
# [3.1.0](https://github.com/strongloop/loopback-next/compare/@loopback/context@3.0.0...@loopback/context@3.1.0) (2020-03-17)

@@ -8,0 +20,0 @@

39

dist/context-view.d.ts

@@ -7,2 +7,3 @@ /// <reference types="node" />

import { Context } from './context';
import { ContextEvent } from './context-event';
import { ContextEventType, ContextObserver } from './context-observer';

@@ -14,2 +15,11 @@ import { Subscription } from './context-subscription';

/**
* An event emitted by a `ContextView`
*/
export interface ContextViewEvent<T> extends ContextEvent {
/**
* Optional cached value for an `unbind` event
*/
cachedValue?: T;
}
/**
* `ContextView` provides a view for a given context chain to maintain a live

@@ -24,2 +34,4 @@ * list of matching bindings and their resolved values within the context

* `ContextView` is an event emitter that emits the following events:
* - 'bind': when a binding is added to the view
* - 'unbind': when a binding is removed from the view
* - 'close': when the view is closed (stopped observing context events)

@@ -30,10 +42,31 @@ * - 'refresh': when the view is refreshed as bindings are added/removed

export declare class ContextView<T = unknown> extends EventEmitter implements ContextObserver {
protected readonly context: Context;
readonly context: Context;
readonly filter: BindingFilter;
readonly comparator?: BindingComparator | undefined;
/**
* An array of cached bindings that matches the binding filter
*/
protected _cachedBindings: Readonly<Binding<T>>[] | undefined;
protected _cachedValues: T[] | undefined;
/**
* A map of cached values by binding
*/
protected _cachedValues: Map<Readonly<Binding<T>>, T> | undefined;
private _subscription;
/**
* Create a context view
* @param context - Context object to watch
* @param filter - Binding filter to match bindings of interest
* @param comparator - Comparator to sort the matched bindings
*/
constructor(context: Context, filter: BindingFilter, comparator?: BindingComparator | undefined);
/**
* Update the cached values keyed by binding
* @param values - An array of resolved values
*/
private updateCachedValues;
/**
* Get an array of cached values
*/
private getCachedValues;
/**
* Start listening events from the context

@@ -58,3 +91,3 @@ */

*/
observe(event: ContextEventType, binding: Readonly<Binding<unknown>>): void;
observe(event: ContextEventType, binding: Readonly<Binding<unknown>>, context: Context): void;
/**

@@ -61,0 +94,0 @@ * Refresh the view by invalidating its cache

@@ -25,2 +25,4 @@ "use strict";

* `ContextView` is an event emitter that emits the following events:
* - 'bind': when a binding is added to the view
* - 'unbind': when a binding is removed from the view
* - 'close': when the view is closed (stopped observing context events)

@@ -31,2 +33,8 @@ * - 'refresh': when the view is refreshed as bindings are added/removed

class ContextView extends events_1.EventEmitter {
/**
* Create a context view
* @param context - Context object to watch
* @param filter - Binding filter to match bindings of interest
* @param comparator - Comparator to sort the matched bindings
*/
constructor(context, filter, comparator) {

@@ -39,2 +47,23 @@ super();

/**
* Update the cached values keyed by binding
* @param values - An array of resolved values
*/
updateCachedValues(values) {
var _a;
if (this._cachedBindings == null)
return undefined;
this._cachedValues = new Map();
for (let i = 0; i < ((_a = this._cachedBindings) === null || _a === void 0 ? void 0 : _a.length); i++) {
this._cachedValues.set(this._cachedBindings[i], values[i]);
}
return this._cachedValues;
}
/**
* Get an array of cached values
*/
getCachedValues() {
var _a, _b;
return Array.from((_b = (_a = this._cachedValues) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : []);
}
/**
* Start listening events from the context

@@ -81,3 +110,6 @@ */

}
this._cachedBindings = found;
/* istanbul ignore if */
if (debug.enabled) {
debug('Bindings found', found.map(b => b.key));
}
return found;

@@ -88,3 +120,17 @@ }

*/
observe(event, binding) {
observe(event, binding, context) {
var _a;
const ctxEvent = {
context,
binding,
type: event,
};
debug('Observed event %s %s %s', event, binding.key, context.name);
if (event === 'unbind') {
const cachedValue = (_a = this._cachedValues) === null || _a === void 0 ? void 0 : _a.get(binding);
this.emit(event, Object.assign(Object.assign({}, ctxEvent), { cachedValue }));
}
else {
this.emit(event, ctxEvent);
}
this.refresh();

@@ -107,5 +153,7 @@ }

debug('Resolving values');
if (this._cachedValues != null)
return this._cachedValues;
let result = value_promise_1.resolveList(this.bindings, b => {
if (this._cachedValues != null) {
return this.getCachedValues();
}
const bindings = this.bindings;
let result = value_promise_1.resolveList(bindings, b => {
return b.getValue(this.context, resolution_session_1.ResolutionSession.fork(session));

@@ -115,3 +163,3 @@ });

result = result.then(values => {
this._cachedValues = values;
this.updateCachedValues(values);
this.emit('resolve', values);

@@ -122,3 +170,4 @@ return values;

else {
this._cachedValues = result;
// Clone the array so that the cached values won't be mutated
this.updateCachedValues(result);
this.emit('resolve', result);

@@ -137,5 +186,5 @@ }

if (this._cachedValues == null) {
this._cachedValues = await this.resolve(session);
return this.resolve(session);
}
return this._cachedValues;
return this.getCachedValues();
}

@@ -142,0 +191,0 @@ /**

14

package.json
{
"name": "@loopback/context",
"version": "3.1.0",
"version": "3.2.0",
"description": "LoopBack's container for Inversion of Control",

@@ -21,3 +21,3 @@ "engines": {

"dependencies": {
"@loopback/metadata": "^2.0.1",
"@loopback/metadata": "^2.0.2",
"debug": "^4.1.1",

@@ -29,9 +29,9 @@ "p-event": "^4.1.0",

"devDependencies": {
"@loopback/build": "^4.0.1",
"@loopback/eslint-config": "^6.0.1",
"@loopback/testlab": "^2.0.1",
"@loopback/build": "^5.0.0",
"@loopback/eslint-config": "^6.0.2",
"@loopback/testlab": "^2.0.2",
"@types/bluebird": "^3.5.30",
"@types/debug": "^4.1.5",
"@types/node": "^10.17.17",
"@types/uuid": "^7.0.0",
"@types/uuid": "^7.0.2",
"bluebird": "^3.7.2"

@@ -61,3 +61,3 @@ },

},
"gitHead": "85a906121febac2dbd2d4adcdc21b5939a770951"
"gitHead": "020ed59b8bed8b38e1e4cede06a22b234effdb57"
}

@@ -13,2 +13,3 @@ // Copyright IBM Corp. 2019,2020. All Rights Reserved.

import {Context} from './context';
import {ContextEvent} from './context-event';
import {ContextEventType, ContextObserver} from './context-observer';

@@ -23,2 +24,12 @@ import {Subscription} from './context-subscription';

/**
* An event emitted by a `ContextView`
*/
export interface ContextViewEvent<T> extends ContextEvent {
/**
* Optional cached value for an `unbind` event
*/
cachedValue?: T;
}
/**
* `ContextView` provides a view for a given context chain to maintain a live

@@ -33,2 +44,4 @@ * list of matching bindings and their resolved values within the context

* `ContextView` is an event emitter that emits the following events:
* - 'bind': when a binding is added to the view
* - 'unbind': when a binding is removed from the view
* - 'close': when the view is closed (stopped observing context events)

@@ -40,8 +53,20 @@ * - 'refresh': when the view is refreshed as bindings are added/removed

implements ContextObserver {
/**
* An array of cached bindings that matches the binding filter
*/
protected _cachedBindings: Readonly<Binding<T>>[] | undefined;
protected _cachedValues: T[] | undefined;
/**
* A map of cached values by binding
*/
protected _cachedValues: Map<Readonly<Binding<T>>, T> | undefined;
private _subscription: Subscription | undefined;
/**
* Create a context view
* @param context - Context object to watch
* @param filter - Binding filter to match bindings of interest
* @param comparator - Comparator to sort the matched bindings
*/
constructor(
protected readonly context: Context,
public readonly context: Context,
public readonly filter: BindingFilter,

@@ -54,2 +79,22 @@ public readonly comparator?: BindingComparator,

/**
* Update the cached values keyed by binding
* @param values - An array of resolved values
*/
private updateCachedValues(values: T[]) {
if (this._cachedBindings == null) return undefined;
this._cachedValues = new Map();
for (let i = 0; i < this._cachedBindings?.length; i++) {
this._cachedValues.set(this._cachedBindings[i], values[i]);
}
return this._cachedValues;
}
/**
* Get an array of cached values
*/
private getCachedValues() {
return Array.from(this._cachedValues?.values() ?? []);
}
/**
* Start listening events from the context

@@ -98,3 +143,9 @@ */

}
this._cachedBindings = found;
/* istanbul ignore if */
if (debug.enabled) {
debug(
'Bindings found',
found.map(b => b.key),
);
}
return found;

@@ -106,3 +157,23 @@ }

*/
observe(event: ContextEventType, binding: Readonly<Binding<unknown>>) {
observe(
event: ContextEventType,
binding: Readonly<Binding<unknown>>,
context: Context,
) {
const ctxEvent: ContextViewEvent<T> = {
context,
binding,
type: event,
};
debug('Observed event %s %s %s', event, binding.key, context.name);
if (event === 'unbind') {
const cachedValue = this._cachedValues?.get(
binding as Readonly<Binding<T>>,
);
this.emit(event, {...ctxEvent, cachedValue});
} else {
this.emit(event, ctxEvent);
}
this.refresh();

@@ -127,4 +198,7 @@ }

debug('Resolving values');
if (this._cachedValues != null) return this._cachedValues;
let result = resolveList(this.bindings, b => {
if (this._cachedValues != null) {
return this.getCachedValues();
}
const bindings = this.bindings;
let result = resolveList(bindings, b => {
return b.getValue(this.context, ResolutionSession.fork(session));

@@ -134,3 +208,3 @@ });

result = result.then(values => {
this._cachedValues = values;
this.updateCachedValues(values);
this.emit('resolve', values);

@@ -140,3 +214,4 @@ return values;

} else {
this._cachedValues = result;
// Clone the array so that the cached values won't be mutated
this.updateCachedValues(result);
this.emit('resolve', result);

@@ -156,5 +231,5 @@ }

if (this._cachedValues == null) {
this._cachedValues = await this.resolve(session);
return this.resolve(session);
}
return this._cachedValues;
return this.getCachedValues();
}

@@ -161,0 +236,0 @@

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