Socket
Socket
Sign inDemoInstall

@aurelia/runtime

Package Overview
Dependencies
Maintainers
1
Versions
1110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aurelia/runtime - npm Package Compare versions

Comparing version 2.1.0-dev.202404150648 to 2.1.0-dev.202405060015

dist/types/observation/connectable.d.ts

15

dist/types/index.d.ts

@@ -1,15 +0,11 @@

export { type ExpressionKind, CallFunctionExpression, CustomExpression, BindingBehaviorExpression, ValueConverterExpression, AssignExpression, ConditionalExpression, AccessThisExpression, AccessGlobalExpression, AccessScopeExpression, AccessBoundaryExpression, AccessMemberExpression, AccessKeyedExpression, CallScopeExpression, CallMemberExpression, BinaryExpression, UnaryExpression, PrimitiveLiteralExpression, ArrayLiteralExpression, ObjectLiteralExpression, TemplateExpression, TaggedTemplateExpression, ArrayBindingPattern, ObjectBindingPattern, BindingIdentifier, ForOfStatement, Interpolation, DestructuringAssignmentExpression, DestructuringAssignmentSingleExpression, DestructuringAssignmentRestExpression, ArrowFunction, astVisit, Unparser, type AnyBindingExpression, type BindingBehaviorInstance, type IsPrimary, type IsLiteral, type IsLeftHandSide, type IsUnary, type IsBinary, type IsConditional, type IsAssign, type IsValueConverter, type IsBindingBehavior, type IsAssignable, type IsExpression, type IsExpressionOrStatement, type IVisitor, type BinaryOperator, type BindingIdentifierOrPattern, type UnaryOperator, type IAstEvaluator, type ValueConverterInstance, } from './binding/ast';
export { astAssign, astBind, astEvaluate, astUnbind, } from './binding/ast.eval';
export { type IConnectableBinding, connectable, BindingObserverRecord, } from './binding/connectable';
export { IExpressionParser, type ExpressionType, parseExpression, } from './binding/expression-parser';
export { type IObserverLocatorBasedConnectable, type IObserverRecord, connectable, } from './observation/connectable';
export { ArrayObserver, ArrayIndexObserver, enableArrayObservation, disableArrayObservation, type IArrayIndexObserver, } from './observation/array-observer';
export { MapObserver, enableMapObservation, disableMapObservation, } from './observation/map-observer';
export { SetObserver, enableSetObservation, disableSetObservation } from './observation/set-observer';
export { BindingContext, Scope, } from './observation/scope';
export { CollectionLengthObserver, CollectionSizeObserver, } from './observation/collection-length-observer';
export { ComputedObserver, type ComputedGetterFn, } from './observation/computed-observer';
export { IDirtyChecker, DirtyChecker, DirtyCheckProperty, DirtyCheckSettings, } from './observation/dirty-checker';
export { type IEffect, IObservation, Observation, type EffectRunFunc, } from './observation/observation';
export { type IEffect, IObservation, Observation, type EffectRunFunc, } from './observation/effect-runner';
export { type IObservableDefinition, observable, } from './observation/observable';
export { type IObjectObservationAdapter, IObserverLocator, INodeObserverLocator, getCollectionObserver, ObserverLocator, getObserverLookup, type ObservableGetter, type ObservableSetter, } from './observation/observer-locator';
export { type IObjectObservationAdapter, IObserverLocator, INodeObserverLocator, IComputedObserverLocator, getCollectionObserver, ObserverLocator, getObserverLookup, type ObservableGetter, } from './observation/observer-locator';
export { PrimitiveObserver, } from './observation/primitive-observer';

@@ -20,7 +16,6 @@ export { PropertyAccessor, } from './observation/property-accessor';

export { SetterObserver, } from './observation/setter-observer';
export { ISignaler, } from './observation/signaler';
export { SubscriberRecord, subscriberCollection, } from './observation/subscriber-collection';
export { subscriberCollection, } from './observation/subscriber-collection';
export { batch, } from './observation/subscriber-batch';
export { ConnectableSwitcher, } from './observation/connectable-switcher';
export { type AccessorOrObserver, type IRateLimitOptions, type IBinding, AccessorType, type Collection, type CollectionKind, type IAccessor, type IBindingContext, type ICollectionChangeTracker, type ICollectionObserver, type IConnectable, type ICollectionSubscriber, type IndexMap, type IObserver, type IObservable, type IOverrideContext, type InterceptorFunc, type ISubscribable, type ISubscriberCollection, type CollectionObserver, type ICollectionSubscriberCollection, type ICollectionSubscribable, type ISubscriber, type ISubscriberRecord, isIndexMap, copyIndexMap, cloneIndexMap, createIndexMap, ICoercionConfiguration, } from './observation';
export { type AccessorOrObserver, AccessorType, type Collection, type CollectionKind, type IAccessor, type ICollectionChangeTracker, type ICollectionObserver, type IConnectable, type ICollectionSubscriber, type IndexMap, type IObserver, type IObservable, type InterceptorFunc, type ISubscribable, type ISubscriberCollection, type CollectionObserver, type ICollectionSubscriberCollection, type ICollectionSubscribable, type ISubscriber, type ISubscriberRecord, isIndexMap, copyIndexMap, cloneIndexMap, createIndexMap, ICoercionConfiguration, } from './observation';
//# sourceMappingURL=index.d.ts.map

@@ -1,20 +0,3 @@

import { IDisposable, IIndexable, IServiceLocator } from '@aurelia/kernel';
import type { Scope } from './observation/scope';
import { IIndexable } from '@aurelia/kernel';
import type { CollectionLengthObserver, CollectionSizeObserver } from './observation/collection-length-observer';
import { TaskQueue } from '@aurelia/platform';
export interface IBinding {
readonly isBound: boolean;
bind(scope: Scope): void;
unbind(): void;
get: IServiceLocator['get'];
useScope?(scope: Scope): void;
limit?(opts: IRateLimitOptions): IDisposable;
}
export interface IRateLimitOptions {
type: 'throttle' | 'debounce';
delay: number;
queue: TaskQueue;
now: () => number;
signals: string[];
}
export declare const ICoercionConfiguration: import("@aurelia/kernel").InterfaceSymbol<ICoercionConfiguration>;

@@ -156,8 +139,2 @@ export interface ICoercionConfiguration {

export type CollectionObserver = ICollectionObserver<CollectionKind>;
export interface IBindingContext {
[key: PropertyKey]: any;
}
export interface IOverrideContext {
[key: PropertyKey]: any;
}
export type IObservable<T = IIndexable> = T & {

@@ -164,0 +141,0 @@ $observers?: IIndexable<{}, AccessorOrObserver>;

import { ICoercionConfiguration, IObserver, InterceptorFunc } from '../observation';
import type { AccessorType, ISubscriber, ICollectionSubscriber, ISubscriberCollection, IConnectable } from '../observation';
import type { IConnectableBinding } from '../binding/connectable';
import type { IObserverLocatorBasedConnectable } from './connectable';
import type { IObserverLocator } from './observer-locator';
export type ComputedGetterFn<T = any, R = any> = (this: T, obj: T, observer: IConnectable) => R;
export interface ComputedObserver<T extends object> extends IConnectableBinding, ISubscriberCollection {
export interface ComputedObserver<T extends object> extends IObserverLocatorBasedConnectable, ISubscriberCollection {
}
export declare class ComputedObserver<T extends object> implements IObserver, IConnectableBinding, ISubscriber, ICollectionSubscriber, ISubscriberCollection {
export declare class ComputedObserver<T extends object> implements IObserver, IObserverLocatorBasedConnectable, ISubscriber, ICollectionSubscriber, ISubscriberCollection {
type: AccessorType;

@@ -10,0 +10,0 @@ /**

@@ -1,3 +0,2 @@

import { AccessorType, IAccessor, ISubscriberCollection } from '../observation';
import type { Constructable } from '@aurelia/kernel';
import { type Constructable } from '@aurelia/kernel';
import type { InterceptorFunc } from '../observation';

@@ -9,17 +8,12 @@ export interface IObservableDefinition {

}
export declare function observable(target: object, key: PropertyKey, descriptor?: PropertyDescriptor & {
initializer?: () => unknown;
}): void;
export declare function observable(config: IObservableDefinition): (target: Constructable | object, ...args: unknown[]) => void;
export declare function observable(key: PropertyKey): ClassDecorator;
export declare function observable(): PropertyDecorator;
export interface SetterNotifier extends IAccessor, ISubscriberCollection {
}
export declare class SetterNotifier implements IAccessor {
static mixed: boolean;
readonly type: AccessorType;
constructor(obj: object, callbackKey: PropertyKey, set: InterceptorFunc | undefined, initialValue: unknown);
getValue(): unknown;
setValue(value: unknown): void;
}
type FieldInitializer<TFThis, TValue> = (this: TFThis, initialValue: TValue) => TValue;
type ObservableFieldDecorator<TFThis, TValue> = (target: undefined, context: ClassFieldDecoratorContext<TFThis, TValue>) => FieldInitializer<TFThis, TValue>;
type ObservableClassDecorator<TCThis extends Constructable> = (target: TCThis, context: ClassDecoratorContext<TCThis>) => void;
export declare const observable: {
<TFThis, TValue>(target: undefined, context: ClassFieldDecoratorContext<TFThis, TValue>): FieldInitializer<TFThis, TValue>;
<TCThis extends Constructable, TFThis_1, TValue_1>(config: IObservableDefinition): (target: TCThis | undefined, context: ClassDecoratorContext<TCThis> | ClassFieldDecoratorContext<TFThis_1, TValue_1>) => void | FieldInitializer<TFThis_1, TValue_1>;
<TCThis_1 extends Constructable>(key: PropertyKey): ObservableClassDecorator<TCThis_1>;
<TFThis_2, TValue_2>(): ObservableFieldDecorator<TFThis_2, TValue_2>;
};
export {};
//# sourceMappingURL=observable.d.ts.map

@@ -17,12 +17,12 @@ import { ComputedGetterFn } from './computed-observer';

export declare const INodeObserverLocator: import("@aurelia/kernel").InterfaceSymbol<INodeObserverLocator>;
export interface IComputedObserverLocator {
getObserver(obj: object, key: PropertyKey, pd: ExtendedPropertyDescriptor, requestor: IObserverLocator): IObserver;
}
export declare const IComputedObserverLocator: import("@aurelia/kernel").InterfaceSymbol<IComputedObserverLocator>;
export type ExtendedPropertyDescriptor = PropertyDescriptor & {
get?: ObservableGetter;
set?: ObservableSetter;
};
export type ObservableGetter = PropertyDescriptor['get'] & {
getObserver?(obj: unknown, requestor: IObserverLocator): IObserver;
getObserver?(obj: unknown): IObserver;
};
export type ObservableSetter = PropertyDescriptor['set'] & {
getObserver?(obj: unknown, requestor: IObserverLocator): IObserver;
};
export declare class ObserverLocator {

@@ -29,0 +29,0 @@ addAdapter(adapter: IObjectObservationAdapter): void;

import { Constructable } from '@aurelia/kernel';
export declare function nowrap(): (target: unknown, context: ClassDecoratorContext | ClassFieldDecoratorContext) => void;
/**
* A decorator to signal proxy observation shouldn't make an effort to wrap an object
*/
export declare function nowrap(target: Constructable): void;
export declare function nowrap(target: object, key: PropertyKey, descriptor?: PropertyDescriptor): void;
export declare function nowrap(): ClassDecorator | PropertyDecorator | any;
export declare function nowrap(target?: Constructable | object, key?: PropertyKey, descriptor?: PropertyDescriptor): ClassDecorator | PropertyDecorator;
export declare function nowrap(target: Constructable, context: ClassDecoratorContext): void;
export declare function nowrap(target: undefined, context: ClassFieldDecoratorContext): void;
//# sourceMappingURL=proxy-decorators.d.ts.map

@@ -1,12 +0,8 @@

import type { Collection, ICollectionSubscriber, IndexMap, ISubscriber, ISubscriberRecord } from '../observation';
import type { ICollectionSubscriber, ISubscriber } from '../observation';
import { Constructable } from '@aurelia/kernel';
export type IAnySubscriber = ISubscriber | ICollectionSubscriber;
export declare function subscriberCollection(): ClassDecorator;
export declare function subscriberCollection(target: Function): void;
export declare class SubscriberRecord<T extends IAnySubscriber> implements ISubscriberRecord<T> {
count: number;
add(subscriber: T): boolean;
remove(subscriber: T): boolean;
notify(val: unknown, oldVal: unknown): void;
notifyCollection(collection: Collection, indexMap: IndexMap): void;
}
export declare const subscriberCollection: {
(): <T extends Constructable>(value: T, context: ClassDecoratorContext) => T;
<T_1 extends Constructable>(target: T_1, context: ClassDecoratorContext): T_1;
};
//# sourceMappingURL=subscriber-collection.d.ts.map
{
"name": "@aurelia/runtime",
"version": "2.1.0-dev.202404150648",
"version": "2.1.0-dev.202405060015",
"main": "dist/cjs/index.cjs",

@@ -57,5 +57,6 @@ "module": "dist/esm/index.mjs",

"dependencies": {
"@aurelia/kernel": "2.1.0-dev.202404150648",
"@aurelia/metadata": "2.1.0-dev.202404150648",
"@aurelia/platform": "2.1.0-dev.202404150648"
"@aurelia/kernel": "2.1.0-dev.202405060015",
"@aurelia/expression-parser": "2.1.0-dev.202405060015",
"@aurelia/metadata": "2.1.0-dev.202405060015",
"@aurelia/platform": "2.1.0-dev.202405060015"
},

@@ -62,0 +63,0 @@ "devDependencies": {

export {
type ExpressionKind,
// Ast nodes
CallFunctionExpression,
CustomExpression,
BindingBehaviorExpression,
ValueConverterExpression,
AssignExpression,
ConditionalExpression,
AccessThisExpression,
AccessGlobalExpression,
AccessScopeExpression,
AccessBoundaryExpression,
AccessMemberExpression,
AccessKeyedExpression,
CallScopeExpression,
CallMemberExpression,
BinaryExpression,
UnaryExpression,
PrimitiveLiteralExpression,
ArrayLiteralExpression,
ObjectLiteralExpression,
TemplateExpression,
TaggedTemplateExpression,
ArrayBindingPattern,
ObjectBindingPattern,
BindingIdentifier,
ForOfStatement,
Interpolation,
DestructuringAssignmentExpression,
DestructuringAssignmentSingleExpression,
DestructuringAssignmentRestExpression,
ArrowFunction,
astVisit,
Unparser,
// ast typing helpers
type AnyBindingExpression,
type BindingBehaviorInstance,
type IsPrimary,
type IsLiteral,
type IsLeftHandSide,
type IsUnary,
type IsBinary,
type IsConditional,
type IsAssign,
type IsValueConverter,
type IsBindingBehavior,
type IsAssignable,
type IsExpression,
type IsExpressionOrStatement,
type IVisitor,
type BinaryOperator,
type BindingIdentifierOrPattern,
type UnaryOperator,
type IAstEvaluator,
type ValueConverterInstance,
} from './binding/ast';
export {
astAssign,
astBind,
astEvaluate,
astUnbind,
} from './binding/ast.eval';
export {
type IConnectableBinding,
type IObserverLocatorBasedConnectable,
type IObserverRecord,
connectable,
BindingObserverRecord,
} from './binding/connectable';
export {
IExpressionParser,
type ExpressionType,
parseExpression,
} from './binding/expression-parser';
} from './observation/connectable';

@@ -95,6 +25,2 @@ export {

export {
BindingContext,
Scope,
} from './observation/scope';
export {
CollectionLengthObserver,

@@ -118,3 +44,3 @@ CollectionSizeObserver,

type EffectRunFunc,
} from './observation/observation';
} from './observation/effect-runner';
export {

@@ -128,2 +54,3 @@ type IObservableDefinition,

INodeObserverLocator,
IComputedObserverLocator,
getCollectionObserver,

@@ -133,3 +60,3 @@ ObserverLocator,

type ObservableGetter,
type ObservableSetter,
// type ObservableSetter,
} from './observation/observer-locator';

@@ -152,6 +79,2 @@ export {

export {
ISignaler,
} from './observation/signaler';
export {
SubscriberRecord,
subscriberCollection,

@@ -168,4 +91,2 @@ } from './observation/subscriber-collection';

type AccessorOrObserver,
type IRateLimitOptions,
type IBinding,
AccessorType,

@@ -175,3 +96,2 @@ type Collection,

type IAccessor,
type IBindingContext,
type ICollectionChangeTracker,

@@ -184,3 +104,2 @@ type ICollectionObserver,

type IObservable,
type IOverrideContext,
type InterceptorFunc,

@@ -187,0 +106,0 @@ type ISubscribable,

@@ -1,25 +0,6 @@

import { DI, IDisposable, IIndexable, IServiceLocator } from '@aurelia/kernel';
import { DI, IIndexable } from '@aurelia/kernel';
import { isArray, objectFreeze } from './utilities';
import type { Scope } from './observation/scope';
import type { CollectionLengthObserver, CollectionSizeObserver } from './observation/collection-length-observer';
import { TaskQueue } from '@aurelia/platform';
export interface IBinding {
readonly isBound: boolean;
bind(scope: Scope): void;
unbind(): void;
get: IServiceLocator['get'];
useScope?(scope: Scope): void;
limit?(opts: IRateLimitOptions): IDisposable;
}
export interface IRateLimitOptions {
type: 'throttle' | 'debounce';
delay: number;
queue: TaskQueue;
now: () => number;
signals: string[];
}
export const ICoercionConfiguration = /*@__PURE__*/DI.createInterface<ICoercionConfiguration>('ICoercionConfiguration');

@@ -258,14 +239,4 @@ export interface ICoercionConfiguration {

export interface IBindingContext {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: PropertyKey]: any;
}
export interface IOverrideContext {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: PropertyKey]: any;
}
export type IObservable<T = IIndexable> = T & {
$observers?: IIndexable<{}, AccessorOrObserver>;
};

@@ -18,3 +18,3 @@ import {

} from './subscriber-collection';
import { def, defineHiddenProp, defineMetadata, getOwnMetadata, isFunction } from '../utilities';
import { def, defineHiddenProp, defineMetadata, getMetadata, isFunction } from '../utilities';
import { addCollectionBatch, batching } from './subscriber-batch';

@@ -372,4 +372,4 @@ import { IIndexable } from '@aurelia/kernel';

// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!(getOwnMetadata(observationEnabledKey, Array) ?? false)) {
defineMetadata(observationEnabledKey, true, Array);
if (!(getMetadata(observationEnabledKey, Array) ?? false)) {
defineMetadata(true, Array, observationEnabledKey);
for (const method of methods) {

@@ -394,2 +394,6 @@ if (proto[method].observing !== true) {

export class ArrayObserver {
static {
subscriberCollection(ArrayObserver, null!);
}
public type: AccessorType = atObserver;

@@ -449,2 +453,5 @@

export class ArrayIndexObserver implements IArrayIndexObserver {
static {
subscriberCollection(ArrayIndexObserver, null!);
}

@@ -513,5 +520,2 @@ public doNotCache: boolean = true;

subscriberCollection(ArrayObserver);
subscriberCollection(ArrayIndexObserver);
export function getArrayObserver(array: unknown[]): ArrayObserver {

@@ -518,0 +522,0 @@ let observer = observerLookup.get(array);

@@ -20,2 +20,6 @@ import { Collection, IObserver, atObserver } from '../observation';

export class CollectionLengthObserver implements IObserver, ICollectionSubscriber {
static {
implementLengthObserver(CollectionLengthObserver);
}
public readonly type: AccessorType = atObserver;

@@ -69,2 +73,6 @@

export class CollectionSizeObserver implements ICollectionSubscriber {
static {
implementLengthObserver(CollectionSizeObserver);
}
public readonly type: AccessorType = atObserver;

@@ -109,3 +117,3 @@

ensureProto(proto, 'unsubscribe', unsubscribe);
subscriberCollection(klass);
return subscriberCollection(klass, null!);
}

@@ -124,4 +132,1 @@

}
implementLengthObserver(CollectionLengthObserver);
implementLengthObserver(CollectionSizeObserver);

@@ -9,3 +9,3 @@ import {

import { enterConnectable, exitConnectable } from './connectable-switcher';
import { connectable } from '../binding/connectable';
import { connectable } from './connectable';
import { wrap, unwrap } from './proxy-observation';

@@ -21,3 +21,3 @@ import { areEqual, isFunction } from '../utilities';

} from '../observation';
import type { IConnectableBinding } from '../binding/connectable';
import type { IObserverLocatorBasedConnectable } from './connectable';
import type { IObserverLocator } from './observer-locator';

@@ -30,10 +30,14 @@ import { ErrorNames, createMappedError } from '../errors';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export interface ComputedObserver<T extends object> extends IConnectableBinding, ISubscriberCollection { }
export interface ComputedObserver<T extends object> extends IObserverLocatorBasedConnectable, ISubscriberCollection { }
export class ComputedObserver<T extends object> implements
IObserver,
IConnectableBinding,
IObserverLocatorBasedConnectable,
ISubscriber,
ICollectionSubscriber,
ISubscriberCollection {
static {
connectable(ComputedObserver, null!);
subscriberCollection(ComputedObserver, null!);
}

@@ -203,4 +207,1 @@ public type: AccessorType = atObserver;

}
connectable(ComputedObserver);
subscriberCollection(ComputedObserver);

@@ -67,3 +67,3 @@ import { IContainer, IPlatform, Registration, resolve } from '@aurelia/kernel';

) {
subscriberCollection(DirtyCheckProperty);
subscriberCollection(DirtyCheckProperty, null!);
}

@@ -70,0 +70,0 @@

import { createIndexMap, atObserver } from '../observation';
import { CollectionSizeObserver } from './collection-length-observer';
import { subscriberCollection } from './subscriber-collection';
import { def, defineHiddenProp, defineMetadata, getOwnMetadata } from '../utilities';
import { def, defineHiddenProp, defineMetadata, getMetadata } from '../utilities';

@@ -135,4 +135,4 @@ import type {

// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!(getOwnMetadata(observationEnabledKey, Map) ?? false)) {
defineMetadata(observationEnabledKey, true, Map);
if (!(getMetadata(observationEnabledKey, Map) ?? false)) {
defineMetadata(true, Map, observationEnabledKey);
for (const method of methods) {

@@ -157,2 +157,6 @@ if (proto[method].observing !== true) {

export class MapObserver {
static {
subscriberCollection(MapObserver, null!);
}
public type: AccessorType = atObserver;

@@ -195,4 +199,2 @@ private lenObs?: CollectionSizeObserver;

subscriberCollection(MapObserver);
export function getMapObserver(map: Map<unknown, unknown>): MapObserver {

@@ -199,0 +201,0 @@ let observer = observerLookup.get(map);

@@ -1,7 +0,7 @@

import { AccessorType, IAccessor, IObserver, ISubscriberCollection, atObserver } from '../observation';
import { AccessorType, IAccessor, ISubscriberCollection, atObserver } from '../observation';
import { safeString, def, isFunction, areEqual } from '../utilities';
import { currentConnectable } from './connectable-switcher';
import type { Constructable, IIndexable } from '@aurelia/kernel';
import type { IBindingContext, InterceptorFunc, IObservable } from '../observation';
import { emptyObject, type Constructable, type IIndexable } from '@aurelia/kernel';
import type { InterceptorFunc, IObservable } from '../observation';
import type { ObservableGetter } from './observer-locator';

@@ -18,215 +18,207 @@ import type { SetterObserver } from './setter-observer';

function getObserversLookup(obj: IObservable): IIndexable<{}, SetterObserver | SetterNotifier> {
if (obj.$observers === void 0) {
def(obj, '$observers', { value: {} });
// todo: define in a weakmap
}
return obj.$observers as IIndexable<{}, SetterObserver | SetterNotifier>;
}
type FieldInitializer<TFThis, TValue> = (this: TFThis, initialValue: TValue) => TValue;
type ObservableFieldDecorator<TFThis, TValue> = (target: undefined, context: ClassFieldDecoratorContext<TFThis, TValue>) => FieldInitializer<TFThis, TValue>;
type ObservableClassDecorator<TCThis extends Constructable> = (target: TCThis, context: ClassDecoratorContext<TCThis>) => void;
const noValue: unknown = {};
export const observable = /*@__PURE__*/(() => {
type SetterObserverOwningObject = IIndexable<IBindingContext, IObserver>;
function getObserversLookup(obj: IObservable): IIndexable<{}, SetterObserver | SetterNotifier> {
if (obj.$observers === void 0) {
def(obj, '$observers', { value: {} });
// todo: define in a weakmap
}
return obj.$observers as IIndexable<{}, SetterObserver | SetterNotifier>;
}
// for
// class {
// @observable prop
// }
export function observable(target: object, key: PropertyKey, descriptor?: PropertyDescriptor & { initializer?: () => unknown }): void;
// for
// @observable({...})
// class {}
// and
// class {
// @observable({...}) prop
// }
export function observable(config: IObservableDefinition): (target: Constructable | object, ...args: unknown[]) => void;
// for
// @observable('') class {}
// @observable(5) class {}
// @observable(Symbol()) class {}
export function observable(key: PropertyKey): ClassDecorator;
// for:
// class {
// @observable() prop
// }
export function observable(): PropertyDecorator;
// impl, wont be seen
export function observable(
targetOrConfig?: Constructable | object | PropertyKey | IObservableDefinition,
key?: PropertyKey,
descriptor?: PropertyDescriptor
): ClassDecorator | PropertyDecorator {
if (!SetterNotifier.mixed) {
SetterNotifier.mixed = true;
subscriberCollection(SetterNotifier);
}
// either this check, or arguments.length === 3
// or could be both, so can throw against user error for better DX
if (key == null) {
// for:
// @observable('prop')
// class {}
//
// @observable({ name: 'prop', callback: ... })
// class {}
//
// class {
// @observable() prop
// @observable({ callback: ... }) prop2
// }
return ((t: Constructable, k: PropertyKey, d: PropertyDescriptor) => deco(t, k, d, targetOrConfig as PropertyKey | IObservableDefinition)) as ClassDecorator;
}
// for:
const noValue: unknown = {};
// for
// class {
// @observable prop
// }
return deco(targetOrConfig, key, descriptor) as PropertyDecorator;
function deco(
target: Constructable | object | PropertyKey | undefined,
key?: PropertyKey,
descriptor?: PropertyDescriptor & { initializer?: CallableFunction },
config?: PropertyKey | IObservableDefinition,
): void | PropertyDescriptor {
// class decorator?
const isClassDecorator = key === void 0;
config = typeof config !== 'object'
? { name: config }
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
: (config || {});
if (isClassDecorator) {
key = config.name;
function observable<TFThis, TValue>(target: undefined, context: ClassFieldDecoratorContext<TFThis, TValue>): FieldInitializer<TFThis, TValue>;
// for
// @observable({...})
// class {}
// and
// class {
// @observable({...}) prop
// }
function observable<TCThis extends Constructable, TFThis, TValue>(config: IObservableDefinition): (target: TCThis | undefined, context: ClassDecoratorContext<TCThis> | ClassFieldDecoratorContext<TFThis, TValue>) => FieldInitializer<TFThis, TValue> | void;
// for
// @observable('') class {}
// @observable(5) class {}
// @observable(Symbol()) class {}
function observable<TCThis extends Constructable>(key: PropertyKey): ObservableClassDecorator<TCThis>;
// for:
// class {
// @observable() prop
// }
function observable<TFThis, TValue>(): ObservableFieldDecorator<TFThis, TValue>;
// impl, wont be seen
function observable<TCThis extends Constructable, TFThis, TValue>(targetOrConfig?: undefined | IObservableDefinition | PropertyKey, context?: ClassFieldDecoratorContext): ObservableClassDecorator<TCThis> | ObservableFieldDecorator<TFThis, TValue> | FieldInitializer<TFThis, TValue> {
if (!SetterNotifier.mixed) {
SetterNotifier.mixed = true;
subscriberCollection(SetterNotifier, null!);
}
if (key == null || key === '') {
throw createMappedError(ErrorNames.invalid_observable_decorator_usage);
let isClassDecorator = false;
let config: IObservableDefinition;
if (typeof targetOrConfig === 'object') {
config = targetOrConfig;
} else if (targetOrConfig != null) {
config = { name: targetOrConfig };
isClassDecorator = true;
} else {
config = emptyObject;
}
// determine callback name based on config or convention.
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing, @typescript-eslint/strict-boolean-expressions
const callback = config.callback || `${safeString(key)}Changed`;
let initialValue = noValue;
if (descriptor) {
// we're adding a getter and setter which means the property descriptor
// cannot have a "value" or "writable" attribute
delete descriptor.value;
delete descriptor.writable;
initialValue = descriptor.initializer?.();
delete descriptor.initializer;
} else {
descriptor = { configurable: true };
// case: @observable() prop
if (arguments.length === 0) {
return function (target: unknown, context: DecoratorContext) {
if (context.kind !== 'field') throw createMappedError(ErrorNames.invalid_observable_decorator_usage);
return createFieldInitializer(context);
};
}
// make the accessor enumerable by default, as fields are enumerable
if (!('enumerable' in descriptor)) {
descriptor.enumerable = true;
// case: @observable prop
if (context?.kind === 'field') return createFieldInitializer(context);
// case: @observable(PropertyKey) class
if (isClassDecorator) {
return function (target: TCThis, context: ClassDecoratorContext<TCThis>) {
createDescriptor(target, config.name!, () => noValue, true);
};
}
// todo(bigopon/fred): discuss string api for converter
const $set = config.set;
descriptor.get = function g(/* @observable */this: SetterObserverOwningObject) {
const notifier = getNotifier(this, key!, callback, initialValue, $set);
currentConnectable()?.subscribeTo(notifier);
return notifier.getValue();
// case: @observable({...}) class | @observable({...}) prop
return function (target: Constructable | undefined, context: ClassFieldDecoratorContext | ClassDecoratorContext) {
switch (context.kind) {
case 'field': return createFieldInitializer(context);
case 'class': return createDescriptor(target, config.name!, () => noValue, true);
default: throw createMappedError(ErrorNames.invalid_observable_decorator_usage);
}
};
descriptor.set = function s(/* @observable */this: SetterObserverOwningObject, newValue: unknown) {
getNotifier(this, key!, callback, initialValue, $set).setValue(newValue);
};
(descriptor.get as ObservableGetter).getObserver = function gO(/* @observable */obj: SetterObserverOwningObject) {
return getNotifier(obj, key!, callback, initialValue, $set);
};
if (isClassDecorator) {
def((target as Constructable).prototype as object, key, descriptor);
} else {
return descriptor;
function createFieldInitializer(context: ClassFieldDecoratorContext): FieldInitializer<TFThis, TValue> {
let $initialValue: TValue;
context.addInitializer(function (this: unknown) {
createDescriptor(this, context.name, () => $initialValue, false);
});
return function (this: TFThis, initialValue: TValue) {
return $initialValue = initialValue;
};
}
function createDescriptor(target: unknown, property: PropertyKey, initialValue: () => unknown, targetIsClass: boolean): void {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing, @typescript-eslint/strict-boolean-expressions
const callback = config.callback || `${safeString(property)}Changed`;
const $set = config.set;
const observableGetter: ObservableGetter = function (this: IObservable) {
const notifier = getNotifier(this, property, callback, initialValue, $set);
currentConnectable()?.subscribeTo(notifier);
return notifier.getValue();
};
observableGetter.getObserver = function (obj: IObservable) {
return getNotifier(obj, property, callback, initialValue, $set);
};
const descriptor = {
enumerable: true,
configurable: true,
get: observableGetter,
set(this: IObservable, newValue: TValue) {
getNotifier(this, property, callback, initialValue, $set).setValue(newValue);
}
};
if (targetIsClass) def((target as Constructable).prototype as object, property, descriptor);
else def(target as object, property, descriptor);
}
}
}
function getNotifier(
obj: SetterObserverOwningObject,
key: PropertyKey,
callbackKey: PropertyKey,
initialValue: unknown,
set: InterceptorFunc | undefined,
): SetterNotifier {
const lookup = getObserversLookup(obj) as unknown as Record<PropertyKey, SetterObserver | SetterNotifier>;
let notifier = lookup[key as string] as SetterNotifier;
if (notifier == null) {
notifier = new SetterNotifier(obj, callbackKey, set, initialValue === noValue ? void 0 : initialValue);
lookup[key as string] = notifier;
function getNotifier(
obj: IObservable,
key: PropertyKey,
callbackKey: PropertyKey,
initialValue: () => unknown,
set: InterceptorFunc | undefined,
): SetterNotifier {
const lookup = getObserversLookup(obj) as unknown as Record<PropertyKey, SetterObserver | SetterNotifier>;
let notifier = lookup[key as string] as SetterNotifier;
if (notifier == null) {
const $initialValue = initialValue();
notifier = new SetterNotifier(obj, callbackKey, set, $initialValue === noValue ? void 0 : $initialValue);
lookup[key as string] = notifier;
}
return notifier;
}
return notifier;
}
type ChangeHandlerCallback = (this: object, value: unknown, oldValue: unknown) => void;
type ChangeHandlerCallback = (this: object, value: unknown, oldValue: unknown) => void;
export interface SetterNotifier extends IAccessor, ISubscriberCollection {}
interface SetterNotifier extends IAccessor, ISubscriberCollection { }
export class SetterNotifier implements IAccessor {
public static mixed = false;
public readonly type: AccessorType = atObserver;
class SetterNotifier implements IAccessor {
public static mixed = false;
public readonly type: AccessorType = atObserver;
/** @internal */
private _value: unknown = void 0;
/** @internal */
private _oldValue: unknown = void 0;
/** @internal */
private readonly cb?: ChangeHandlerCallback;
/** @internal */
private readonly _obj: object;
/** @internal */
private readonly _setter: InterceptorFunc | undefined;
/** @internal */
private readonly _hasSetter: boolean;
/** @internal */
private _value: unknown = void 0;
/** @internal */
private _oldValue: unknown = void 0;
/** @internal */
private readonly cb?: ChangeHandlerCallback;
/** @internal */
private readonly _obj: object;
/** @internal */
private readonly _setter: InterceptorFunc | undefined;
/** @internal */
private readonly _hasSetter: boolean;
public constructor(
obj: object,
callbackKey: PropertyKey,
set: InterceptorFunc | undefined,
initialValue: unknown,
) {
this._obj = obj;
this._setter = set;
this._hasSetter = isFunction(set);
const callback = (obj as IIndexable)[callbackKey as string];
this.cb = isFunction(callback) ? callback as ChangeHandlerCallback : void 0;
this._value = initialValue;
}
public constructor(
obj: object,
callbackKey: PropertyKey,
set: InterceptorFunc | undefined,
initialValue: unknown,
) {
this._obj = obj;
this._setter = set;
this._hasSetter = isFunction(set);
const callback = (obj as IIndexable)[callbackKey as string];
this.cb = isFunction(callback) ? callback as ChangeHandlerCallback : void 0;
this._value = initialValue;
}
public getValue(): unknown {
return this._value;
}
public getValue(): unknown {
return this._value;
}
public setValue(value: unknown): void {
if (this._hasSetter) {
value = this._setter!(value);
public setValue(value: unknown): void {
if (this._hasSetter) {
value = this._setter!(value);
}
if (!areEqual(value, this._value)) {
this._oldValue = this._value;
this._value = value;
this.cb?.call(this._obj, this._value, this._oldValue);
// this._value might have been updated during the callback
// we only want to notify subscribers with the latest values
value = this._oldValue;
this._oldValue = this._value;
this.subs.notify(this._value, value);
}
}
if (!areEqual(value, this._value)) {
this._oldValue = this._value;
this._value = value;
this.cb?.call(this._obj, this._value, this._oldValue);
// this._value might have been updated during the callback
// we only want to notify subscribers with the latest values
value = this._oldValue;
this._oldValue = this._value;
this.subs.notify(this._value, value);
}
}
}
/*
| typescript | babel
----------|------------------|-------------------------
property | config | config
w/parens | target, key | target, key, descriptor
----------|------------------|-------------------------
property | target, key | target, key, descriptor
no parens | n/a | n/a
----------|------------------|-------------------------
class | config | config
| target | target
*/
/*
| typescript | babel
----------|------------------|-------------------------
property | config | config
w/parens | target, key | target, key, descriptor
----------|------------------|-------------------------
property | target, key | target, key, descriptor
no parens | n/a | n/a
----------|------------------|-------------------------
class | config | config
| target | target
*/
return observable;
})();

@@ -58,12 +58,30 @@ import { Primitive, isArrayIndex, ILogger, resolve } from '@aurelia/kernel';

export interface IComputedObserverLocator {
getObserver(obj: object, key: PropertyKey, pd: ExtendedPropertyDescriptor, requestor: IObserverLocator): IObserver;
}
export const IComputedObserverLocator = /*@__PURE__*/createInterface<IComputedObserverLocator>(
'IComputedObserverLocator',
x => x.singleton(class DefaultLocator implements IComputedObserverLocator {
public getObserver(obj: object, key: PropertyKey, pd: ExtendedPropertyDescriptor, requestor: IObserverLocator): IObserver {
const observer = new ComputedObserver(obj, pd.get!, pd.set, requestor, true);
def(obj, key, {
enumerable: pd.enumerable,
configurable: true,
get: objectAssign(((/* Computed Observer */) => observer.getValue()) as ObservableGetter, { getObserver: () => observer }),
set: (/* Computed Observer */v) => {
observer.setValue(v);
},
});
return observer;
}
})
);
export type ExtendedPropertyDescriptor = PropertyDescriptor & {
get?: ObservableGetter;
set?: ObservableSetter;
};
export type ObservableGetter = PropertyDescriptor['get'] & {
getObserver?(obj: unknown, requestor: IObserverLocator): IObserver;
getObserver?(obj: unknown): IObserver;
};
export type ObservableSetter = PropertyDescriptor['set'] & {
getObserver?(obj: unknown, requestor: IObserverLocator): IObserver;
};

@@ -74,2 +92,3 @@ export class ObserverLocator {

/** @internal */ private readonly _nodeObserverLocator = resolve(INodeObserverLocator);
/** @internal */ private readonly _computedObserverLocator = resolve(IComputedObserverLocator);

@@ -170,3 +189,3 @@ public addAdapter(adapter: IObjectObservationAdapter): void {

if (obs == null) {
obs = (pd.get?.getObserver ?? pd.set?.getObserver)?.(obj, this);
obs = (pd.get?.getObserver)?.(obj);
}

@@ -177,3 +196,4 @@

? pd.configurable
? this._createComputedObserver(obj, key, pd, true)
// ? this._createComputedObserver(obj, key, pd, true)
? this._computedObserverLocator.getObserver(obj, key, pd, this)
: this._dirtyChecker.createProperty(obj, key)

@@ -188,16 +208,16 @@ : obs;

/** @internal */
private _createComputedObserver(obj: object, key: PropertyKey, pd: PropertyDescriptor, useProxy?: boolean) {
const observer = new ComputedObserver(obj, pd.get!, pd.set, this, !!useProxy);
def(obj, key, {
enumerable: pd.enumerable,
configurable: true,
get: objectAssign(((/* Computed Observer */) => observer.getValue()) as ObservableGetter, { getObserver: () => observer }),
set: (/* Computed Observer */v) => {
observer.setValue(v);
},
});
// /** @internal */
// private _createComputedObserver(obj: object, key: PropertyKey, pd: PropertyDescriptor, useProxy?: boolean) {
// const observer = new ComputedObserver(obj, pd.get!, pd.set, this, !!useProxy);
// def(obj, key, {
// enumerable: pd.enumerable,
// configurable: true,
// get: objectAssign(((/* Computed Observer */) => observer.getValue()) as ObservableGetter, { getObserver: () => observer }),
// set: (/* Computed Observer */v) => {
// observer.setValue(v);
// },
// });
return observer;
}
// return observer;
// }

@@ -204,0 +224,0 @@ /** @internal */

@@ -1,5 +0,6 @@

import { Constructable } from '@aurelia/kernel';
import { Class, Constructable } from '@aurelia/kernel';
import { defineHiddenProp, safeString } from '../utilities';
import { nowrapClassKey, nowrapPropKey } from './proxy-observation';
export function nowrap(): (target: unknown, context: ClassDecoratorContext | ClassFieldDecoratorContext) => void;
/**

@@ -11,4 +12,3 @@ * A decorator to signal proxy observation shouldn't make an effort to wrap an object

// class {}
export function nowrap(target: Constructable): void;
export function nowrap(target: Constructable, context: ClassDecoratorContext): void;
// for

@@ -18,55 +18,31 @@ // class {

// }
export function nowrap(target: object, key: PropertyKey, descriptor?: PropertyDescriptor): void;
// for
// @nowrap()
// class {}
// or
// class { @nowrap() prop }
// returning any just for TS, as it is unable to selectively choose whether it's a class decorator or prop decorator
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents
export function nowrap(): ClassDecorator | PropertyDecorator | any; // (target: Constructable | object, key: PropertyKey, descriptor?: PropertyDescriptor) => void;
// base signature
export function nowrap(
target?: Constructable | object,
key?: PropertyKey,
descriptor?: PropertyDescriptor
): ClassDecorator | PropertyDecorator;
export function nowrap(target: undefined, context: ClassFieldDecoratorContext): void;
/**
* A decorator to signal proxy observation shouldn't make an effort to wrap an object
*/
export function nowrap(
target?: Constructable | object,
key?: PropertyKey
): void | ClassDecorator | PropertyDecorator {
if (target == null) {
// for
// @nowrap()
// class {}
// or
// class { @nowrap() prop }
return (t: Constructable | object, k?: PropertyKey) => deco(t, k);
} else {
// for
// @nowrap
// class {}
// or
// class {
// @nowrap prop
// }
return deco(target, key);
}
export function nowrap<
TThis extends object
>(
target?: Class<TThis> | undefined,
context?: ClassDecoratorContext<Class<TThis>> | ClassFieldDecoratorContext<TThis>
): void
| ((target: unknown, context: ClassDecoratorContext | ClassFieldDecoratorContext) => void) {
return arguments.length === 0 ? decorator : decorator(target!, context!);
function deco(
target: Constructable | object,
key?: PropertyKey
): void | ClassDecorator | PropertyDecorator {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
const isClassDecorator = !key;
if (isClassDecorator) {
defineHiddenProp(target, nowrapClassKey, true);
} else {
// defining on the constructor means inheritance lookup is supported
defineHiddenProp((target as object).constructor, `${nowrapPropKey}_${safeString(key)}__`, true);
function decorator(
target: unknown,
context: ClassDecoratorContext<Class<TThis>> | ClassFieldDecoratorContext<TThis>
): void {
switch (context.kind) {
case 'class':
defineHiddenProp(target as Class<TThis>, nowrapClassKey, true);
break;
case 'field':
context.addInitializer(function (this: object) {
const target = this.constructor;
const property = `${nowrapPropKey}_${safeString(context.name)}__`;
if (property in target) return;
defineHiddenProp(target, property, true);
});
break;
}

@@ -84,11 +60,8 @@ }

class MyModel2 {}
class MyModel3 {
@nowrap public prop = 1;
@nowrap() public prop1 = 1;
}
class MyModel4 {
@nowrap() public prop = 2;
}
}
/* eslint-enable */
import { createIndexMap, type AccessorType, type ICollectionSubscriberCollection, type ICollectionObserver, atObserver } from '../observation';
import { CollectionSizeObserver } from './collection-length-observer';
import { subscriberCollection } from './subscriber-collection';
import { def, defineHiddenProp, defineMetadata, getOwnMetadata } from '../utilities';
import { def, defineHiddenProp, defineMetadata, getMetadata } from '../utilities';
import { batching, addCollectionBatch } from './subscriber-batch';

@@ -115,4 +115,4 @@ import { IIndexable } from '@aurelia/kernel';

// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!(getOwnMetadata(observationEnabledKey, Set) ?? false)) {
defineMetadata(observationEnabledKey, true, Set);
if (!(getMetadata(observationEnabledKey, Set) ?? false)) {
defineMetadata(true, Set, observationEnabledKey);
for (const method of methods) {

@@ -137,2 +137,6 @@ if (proto[method].observing !== true) {

export class SetObserver {
static {
subscriberCollection(SetObserver, null!);
}
public type: AccessorType = atObserver;

@@ -175,4 +179,2 @@ private lenObs?: CollectionSizeObserver;

subscriberCollection(SetObserver);
export function getSetObserver(observedSet: Set<unknown>): SetObserver {

@@ -179,0 +181,0 @@ let observer = observerLookup.get(observedSet);

@@ -19,2 +19,6 @@ import { ICoercionConfiguration, IObserver, InterceptorFunc, atObserver } from '../observation';

export class SetterObserver implements IObserver, ISubscriberCollection {
static {
subscriberCollection(SetterObserver, null!);
}
// todo(bigopon): tweak the flag based on typeof obj (array/set/map/iterator/proxy etc...)

@@ -130,6 +134,4 @@ public type: AccessorType = atObserver;

subscriberCollection(SetterObserver);
// a reusable variable for `.flush()` methods of observers
// so that there doesn't need to create an env record for every call
let oV: unknown = void 0;

@@ -12,94 +12,99 @@ import { def, defineHiddenProp, ensureProto } from '../utilities';

import { addValueBatch, batching } from './subscriber-batch';
import { Class, Constructable } from '@aurelia/kernel';
export type IAnySubscriber = ISubscriber | ICollectionSubscriber;
/* eslint-disable @typescript-eslint/ban-types */
export function subscriberCollection(): ClassDecorator;
export function subscriberCollection(target: Function): void;
export function subscriberCollection(target?: Function): ClassDecorator | void {
return target == null ? subscriberCollectionDeco : subscriberCollectionDeco(target);
}
export const subscriberCollection = /*@__PURE__*/(() => {
const decoratedTarget = new WeakSet<Function>();
function subscriberCollectionDeco(target: Function): void { // ClassDecorator expects it to be derived from Function
if (decoratedTarget.has(target)) {
return;
function subscriberCollection(): <T extends Constructable>(value: T, context: ClassDecoratorContext) => T;
function subscriberCollection<T extends Constructable>(target: T, context: ClassDecoratorContext): T;
function subscriberCollection<T extends Constructable>(target?: T, context?: ClassDecoratorContext<T>): ((value: T, context: ClassDecoratorContext) => T) | T {
return target == null ? subscriberCollectionDeco : subscriberCollectionDeco(target, context!);
}
decoratedTarget.add(target);
const proto = target.prototype as ISubscriberCollection;
// not configurable, as in devtool, the getter could be invoked on the prototype,
// and become permanently broken
def(proto, 'subs', { get: getSubscriberRecord });
ensureProto(proto, 'subscribe', addSubscriber);
ensureProto(proto, 'unsubscribe', removeSubscriber);
}
/* eslint-enable @typescript-eslint/ban-types */
function getSubscriberRecord(this: ISubscriberCollection) {
return defineHiddenProp(this, 'subs', new SubscriberRecord());
}
export class SubscriberRecord<T extends IAnySubscriber> implements ISubscriberRecord<T> {
public count: number = 0;
/** @internal */
private readonly _subs: T[] = [];
function addSubscriber(this: ISubscriberCollection, subscriber: IAnySubscriber): boolean {
return this.subs.add(subscriber as ISubscriber & ICollectionSubscriber);
}
public add(subscriber: T): boolean {
if (this._subs.includes(subscriber)) {
return false;
function removeSubscriber(this: ISubscriberCollection, subscriber: IAnySubscriber): boolean {
return this.subs.remove(subscriber as ISubscriber & ICollectionSubscriber);
}
const decoratedTarget = new WeakSet<Constructable>();
function subscriberCollectionDeco<TObj extends object, T extends Class<TObj>>(target: T, context: ClassDecoratorContext): T { // ClassDecorator expects it to be derived from Function
if (!decoratedTarget.has(target)) {
decoratedTarget.add(target);
const proto = target.prototype as ISubscriberCollection;
// not configurable, as in devtool, the getter could be invoked on the prototype,
// and become permanently broken
def(proto, 'subs', { get: getSubscriberRecord });
ensureProto(proto, 'subscribe', addSubscriber);
ensureProto(proto, 'unsubscribe', removeSubscriber);
}
this._subs[this._subs.length] = subscriber;
++this.count;
return true;
return target;
}
public remove(subscriber: T): boolean {
const idx = this._subs.indexOf(subscriber);
if (idx !== -1) {
this._subs.splice(idx, 1);
--this.count;
class SubscriberRecord<T extends IAnySubscriber> implements ISubscriberRecord<T> {
public count: number = 0;
/** @internal */
private readonly _subs: T[] = [];
public add(subscriber: T): boolean {
if (this._subs.includes(subscriber)) {
return false;
}
this._subs[this._subs.length] = subscriber;
++this.count;
return true;
}
return false;
}
public notify(val: unknown, oldVal: unknown): void {
if (batching) {
addValueBatch(this, val, oldVal);
public remove(subscriber: T): boolean {
const idx = this._subs.indexOf(subscriber);
if (idx !== -1) {
this._subs.splice(idx, 1);
--this.count;
return true;
}
return false;
}
public notify(val: unknown, oldVal: unknown): void {
if (batching) {
addValueBatch(this, val, oldVal);
return;
}
/**
* Note: change handlers may have the side-effect of adding/removing subscribers to this collection during this
* callSubscribers invocation, so we're caching them all before invoking any.
* Subscribers added during this invocation are not invoked (and they shouldn't be).
* Subscribers removed during this invocation will still be invoked (and they also shouldn't be,
* however this is accounted for via $isBound and similar flags on the subscriber objects)
*/
const _subs = this._subs.slice(0) as ISubscriber[];
const len = _subs.length;
let i = 0;
for (; i < len; ++i) {
_subs[i].handleChange(val, oldVal);
}
return;
}
/**
* Note: change handlers may have the side-effect of adding/removing subscribers to this collection during this
* callSubscribers invocation, so we're caching them all before invoking any.
* Subscribers added during this invocation are not invoked (and they shouldn't be).
* Subscribers removed during this invocation will still be invoked (and they also shouldn't be,
* however this is accounted for via $isBound and similar flags on the subscriber objects)
*/
const _subs = this._subs.slice(0) as ISubscriber[];
const len = _subs.length;
let i = 0;
for (; i < len; ++i) {
_subs[i].handleChange(val, oldVal);
}
return;
}
public notifyCollection(collection: Collection, indexMap: IndexMap): void {
const _subs = this._subs.slice(0) as ICollectionSubscriber[];
const len = _subs.length;
let i = 0;
for (; i < len; ++i) {
_subs[i].handleCollectionChange(collection, indexMap);
public notifyCollection(collection: Collection, indexMap: IndexMap): void {
const _subs = this._subs.slice(0) as ICollectionSubscriber[];
const len = _subs.length;
let i = 0;
for (; i < len; ++i) {
_subs[i].handleCollectionChange(collection, indexMap);
}
return;
}
return;
}
}
function getSubscriberRecord(this: ISubscriberCollection) {
return defineHiddenProp(this, 'subs', new SubscriberRecord());
}
function addSubscriber(this: ISubscriberCollection, subscriber: IAnySubscriber): boolean {
return this.subs.add(subscriber as ISubscriber & ICollectionSubscriber);
}
function removeSubscriber(this: ISubscriberCollection, subscriber: IAnySubscriber): boolean {
return this.subs.remove(subscriber as ISubscriber & ICollectionSubscriber);
}
return subscriberCollection;
})();

@@ -76,4 +76,3 @@ import { Metadata } from '@aurelia/metadata';

/** @internal */ export const getOwnMetadata = Metadata.getOwn;
/** @internal */ export const hasOwnMetadata = Metadata.hasOwn;
/** @internal */ export const getMetadata = Metadata.get;
/** @internal */ export const defineMetadata = Metadata.define;

Sorry, the diff of this file is too big to display

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

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

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

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