Comparing version 0.2.9 to 0.3.0-rc.0
@@ -1,6 +0,5 @@ | ||
declare const $get: unique symbol; | ||
declare const $observers: unique symbol; | ||
export { FluidValue, hasFluidValue, getFluidValue, getFluidObservers, callFluidObserver, callFluidObservers, setFluidGetter, addFluidObserver, removeFluidObserver, }; | ||
/** Returns true if `arg` can be observed. */ | ||
declare const hasFluidValue: (arg: any) => arg is FluidValue<any, UnknownFluidEvent<any>>; | ||
declare const hasFluidValue: (arg: any) => arg is FluidValue<any>; | ||
/** | ||
@@ -17,3 +16,3 @@ * Get the current value. | ||
/** Send an event to all observers. */ | ||
declare function callFluidObservers<E extends FluidEvent>(target: FluidValue<any, E>, event: E): void; | ||
declare function callFluidObservers<E extends FluidEvent>(target: FluidObservable<E>, event: E): void; | ||
declare function callFluidObservers(target: object, event: UnsafeFluidEvent): void; | ||
@@ -24,27 +23,38 @@ declare type GetFluidValue = { | ||
declare type GetFluidObservers = { | ||
<E extends FluidEvent>(target: FluidValue<any, E>): ReadonlySet<FluidObserver<E>> | null; | ||
<E extends FluidEvent>(target: FluidObservable<E>): ReadonlySet<FluidObserver<E>> | null; | ||
(target: object): ReadonlySet<FluidObserver> | null; | ||
}; | ||
/** An event from a `FluidValue` instance */ | ||
export interface FluidEvent<T = any> { | ||
/** An event from a `fluids` compatible object */ | ||
export interface FluidEvent<T extends object = any> { | ||
type: string; | ||
parent: FluidValue<T>; | ||
parent: T; | ||
} | ||
/** An event from any `FluidValue` instance */ | ||
export interface UnknownFluidEvent<T = any> extends FluidEvent<T> { | ||
/** An unknown event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent<T extends object = any> extends FluidEvent<T> { | ||
[key: string]: any; | ||
} | ||
/** An untyped event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent { | ||
type: string; | ||
parent: object; | ||
[key: string]: any; | ||
/** | ||
* A source of `FluidEvent` objects that can be observed with | ||
* the `addFluidObserver` function. | ||
* | ||
* Use "interface merging" to mark your class as observable: | ||
* | ||
* class Foo {} | ||
* interface Foo extends FluidObservable<FooEvent> {} | ||
* | ||
* Once that's done, you get the following benefits: | ||
* - observers added with `addFluidObserver` are type-checked | ||
* - events passed to `callFluidObservers` are type-checked | ||
*/ | ||
export interface FluidObservable<E extends FluidEvent = any> { | ||
[$observers]?: E | null; | ||
} | ||
/** | ||
* Extend this class for automatic TypeScript support when passing | ||
* an object to a `fluids` compatible function. | ||
* `FluidValue` objects can be unwrapped with `getFluidValue` to access | ||
* their current value. | ||
* | ||
* Libraries may support observable values by handling `FluidValue` objects | ||
* in their functions and classes. | ||
*/ | ||
declare abstract class FluidValue<T = any, E extends FluidEvent<T> = UnknownFluidEvent<T>> { | ||
protected [$get]: () => T; | ||
protected [$observers]?: Set<FluidObserver<E>>; | ||
declare abstract class FluidValue<T = any> { | ||
constructor(get?: () => T); | ||
@@ -54,5 +64,5 @@ /** Get the current value. */ | ||
/** Called after an observer is added. */ | ||
protected observerAdded?(count: number, observer: FluidObserver): void; | ||
protected observerAdded?(count: number, observer: FluidObserver<any>): void; | ||
/** Called after an observer is removed. */ | ||
protected observerRemoved?(count: number, observer: FluidObserver): void; | ||
protected observerRemoved?(count: number, observer: FluidObserver<any>): void; | ||
} | ||
@@ -76,6 +86,6 @@ /** An observer of `FluidValue` objects. */ | ||
/** Observe a `fluids`-compatible object. */ | ||
declare function addFluidObserver<T, E extends FluidEvent>(target: FluidValue<T, E>, observer: FluidObserver<E>): typeof observer; | ||
declare function addFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): typeof observer; | ||
declare function addFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): typeof observer; | ||
/** Stop observing a `fluids`-compatible object. */ | ||
declare function removeFluidObserver<E extends FluidEvent>(target: FluidValue<any, E>, observer: FluidObserver<E>): void; | ||
declare function removeFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): void; | ||
declare function removeFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): void; |
@@ -41,4 +41,7 @@ "use strict"; | ||
/** | ||
* Extend this class for automatic TypeScript support when passing | ||
* an object to a `fluids` compatible function. | ||
* `FluidValue` objects can be unwrapped with `getFluidValue` to access | ||
* their current value. | ||
* | ||
* Libraries may support observable values by handling `FluidValue` objects | ||
* in their functions and classes. | ||
*/ | ||
@@ -61,13 +64,11 @@ var FluidValue = /** @class */ (function () { | ||
function addFluidObserver(target, observer) { | ||
if (target[$get]) { | ||
var observers = target[$observers]; | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())); | ||
var observers = target[$observers]; | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())); | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer); | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer); | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer); | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer); | ||
} | ||
} | ||
} | ||
@@ -74,0 +75,0 @@ return observer; |
@@ -1,6 +0,5 @@ | ||
declare const $get: unique symbol; | ||
declare const $observers: unique symbol; | ||
export { FluidValue, hasFluidValue, getFluidValue, getFluidObservers, callFluidObserver, callFluidObservers, setFluidGetter, addFluidObserver, removeFluidObserver, }; | ||
/** Returns true if `arg` can be observed. */ | ||
declare const hasFluidValue: (arg: any) => arg is FluidValue<any, UnknownFluidEvent<any>>; | ||
declare const hasFluidValue: (arg: any) => arg is FluidValue<any>; | ||
/** | ||
@@ -17,3 +16,3 @@ * Get the current value. | ||
/** Send an event to all observers. */ | ||
declare function callFluidObservers<E extends FluidEvent>(target: FluidValue<any, E>, event: E): void; | ||
declare function callFluidObservers<E extends FluidEvent>(target: FluidObservable<E>, event: E): void; | ||
declare function callFluidObservers(target: object, event: UnsafeFluidEvent): void; | ||
@@ -24,27 +23,38 @@ declare type GetFluidValue = { | ||
declare type GetFluidObservers = { | ||
<E extends FluidEvent>(target: FluidValue<any, E>): ReadonlySet<FluidObserver<E>> | null; | ||
<E extends FluidEvent>(target: FluidObservable<E>): ReadonlySet<FluidObserver<E>> | null; | ||
(target: object): ReadonlySet<FluidObserver> | null; | ||
}; | ||
/** An event from a `FluidValue` instance */ | ||
export interface FluidEvent<T = any> { | ||
/** An event from a `fluids` compatible object */ | ||
export interface FluidEvent<T extends object = any> { | ||
type: string; | ||
parent: FluidValue<T>; | ||
parent: T; | ||
} | ||
/** An event from any `FluidValue` instance */ | ||
export interface UnknownFluidEvent<T = any> extends FluidEvent<T> { | ||
/** An unknown event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent<T extends object = any> extends FluidEvent<T> { | ||
[key: string]: any; | ||
} | ||
/** An untyped event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent { | ||
type: string; | ||
parent: object; | ||
[key: string]: any; | ||
/** | ||
* A source of `FluidEvent` objects that can be observed with | ||
* the `addFluidObserver` function. | ||
* | ||
* Use "interface merging" to mark your class as observable: | ||
* | ||
* class Foo {} | ||
* interface Foo extends FluidObservable<FooEvent> {} | ||
* | ||
* Once that's done, you get the following benefits: | ||
* - observers added with `addFluidObserver` are type-checked | ||
* - events passed to `callFluidObservers` are type-checked | ||
*/ | ||
export interface FluidObservable<E extends FluidEvent = any> { | ||
[$observers]?: E | null; | ||
} | ||
/** | ||
* Extend this class for automatic TypeScript support when passing | ||
* an object to a `fluids` compatible function. | ||
* `FluidValue` objects can be unwrapped with `getFluidValue` to access | ||
* their current value. | ||
* | ||
* Libraries may support observable values by handling `FluidValue` objects | ||
* in their functions and classes. | ||
*/ | ||
declare abstract class FluidValue<T = any, E extends FluidEvent<T> = UnknownFluidEvent<T>> { | ||
protected [$get]: () => T; | ||
protected [$observers]?: Set<FluidObserver<E>>; | ||
declare abstract class FluidValue<T = any> { | ||
constructor(get?: () => T); | ||
@@ -54,5 +64,5 @@ /** Get the current value. */ | ||
/** Called after an observer is added. */ | ||
protected observerAdded?(count: number, observer: FluidObserver): void; | ||
protected observerAdded?(count: number, observer: FluidObserver<any>): void; | ||
/** Called after an observer is removed. */ | ||
protected observerRemoved?(count: number, observer: FluidObserver): void; | ||
protected observerRemoved?(count: number, observer: FluidObserver<any>): void; | ||
} | ||
@@ -76,6 +86,6 @@ /** An observer of `FluidValue` objects. */ | ||
/** Observe a `fluids`-compatible object. */ | ||
declare function addFluidObserver<T, E extends FluidEvent>(target: FluidValue<T, E>, observer: FluidObserver<E>): typeof observer; | ||
declare function addFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): typeof observer; | ||
declare function addFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): typeof observer; | ||
/** Stop observing a `fluids`-compatible object. */ | ||
declare function removeFluidObserver<E extends FluidEvent>(target: FluidValue<any, E>, observer: FluidObserver<E>): void; | ||
declare function removeFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): void; | ||
declare function removeFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): void; |
@@ -36,4 +36,7 @@ var $get = Symbol.for('FluidValue.get'); | ||
/** | ||
* Extend this class for automatic TypeScript support when passing | ||
* an object to a `fluids` compatible function. | ||
* `FluidValue` objects can be unwrapped with `getFluidValue` to access | ||
* their current value. | ||
* | ||
* Libraries may support observable values by handling `FluidValue` objects | ||
* in their functions and classes. | ||
*/ | ||
@@ -54,13 +57,11 @@ var FluidValue = /** @class */ (function () { | ||
function addFluidObserver(target, observer) { | ||
if (target[$get]) { | ||
var observers = target[$observers]; | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())); | ||
var observers = target[$observers]; | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())); | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer); | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer); | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer); | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer); | ||
} | ||
} | ||
} | ||
@@ -67,0 +68,0 @@ return observer; |
{ | ||
"name": "fluids", | ||
"version": "0.2.9", | ||
"version": "0.3.0-rc.0", | ||
"description": "Glue layer for reactivity", | ||
@@ -5,0 +5,0 @@ "main": "dist/cjs/index", |
@@ -13,3 +13,3 @@ # fluids | ||
Any object can be observed, but `FluidValue` objects have strongly typed | ||
Any object can be observed, but `FluidValue` objects have strongly typed | ||
events. Observed objects are basically event emitters whose listeners | ||
@@ -24,3 +24,3 @@ receive every event, and they typically represent a single value. | ||
// You can pass a function: | ||
let observer = addFluidObserver(target, event => { | ||
let observer = addFluidObserver(target, (event) => { | ||
console.log(event) | ||
@@ -33,3 +33,3 @@ }) | ||
console.log(event) | ||
} | ||
}, | ||
}) | ||
@@ -52,9 +52,13 @@ ``` | ||
```ts | ||
import { FluidValue, callFluidObservers } from 'fluids' | ||
import { FluidValue, FluidObservable, callFluidObservers } from 'fluids' | ||
// Your class can have multiple event types. | ||
type RefEvent<T> = { type: 'change', value: T, parent: Ref<T> } | ||
// The `type` and `parent` properties are required. | ||
type RefEvent<T> = { type: 'change'; value: T; parent: Ref<T> } | ||
// Use "interface merging" to attach the event types. | ||
interface Ref<T> extends FluidObservable<RefEvent<T>> {} | ||
// This example is an observable React ref. | ||
class Ref<T> extends FluidValue<T, RefEvent<T>> { | ||
class Ref<T> extends FluidValue<T> { | ||
private _current: T | ||
@@ -118,3 +122,3 @@ constructor(initialValue: T) { | ||
}) | ||
} | ||
}, | ||
}) | ||
@@ -128,3 +132,8 @@ ``` | ||
```ts | ||
import { hasFluidValue, getFluidValue, getFluidObservers, callFluidObserver } from 'fluids' | ||
import { | ||
hasFluidValue, | ||
getFluidValue, | ||
getFluidObservers, | ||
callFluidObserver, | ||
} from 'fluids' | ||
@@ -131,0 +140,0 @@ // Check if a value is observable. |
@@ -55,3 +55,3 @@ const $get = Symbol.for('FluidValue.get') | ||
function callFluidObservers<E extends FluidEvent>( | ||
target: FluidValue<any, E>, | ||
target: FluidObservable<E>, | ||
event: E | ||
@@ -76,3 +76,3 @@ ): void | ||
type GetFluidObservers = { | ||
<E extends FluidEvent>(target: FluidValue<any, E>): ReadonlySet< | ||
<E extends FluidEvent>(target: FluidObservable<E>): ReadonlySet< | ||
FluidObserver<E> | ||
@@ -83,31 +83,40 @@ > | null | ||
/** An event from a `FluidValue` instance */ | ||
export interface FluidEvent<T = any> { | ||
/** An event from a `fluids` compatible object */ | ||
export interface FluidEvent<T extends object = any> { | ||
type: string | ||
parent: FluidValue<T> | ||
parent: T | ||
} | ||
/** An event from any `FluidValue` instance */ | ||
export interface UnknownFluidEvent<T = any> extends FluidEvent<T> { | ||
/** An unknown event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent<T extends object = any> | ||
extends FluidEvent<T> { | ||
[key: string]: any | ||
} | ||
/** An untyped event from a `fluids` compatible object */ | ||
export interface UnsafeFluidEvent { | ||
type: string | ||
parent: object | ||
[key: string]: any | ||
/** | ||
* A source of `FluidEvent` objects that can be observed with | ||
* the `addFluidObserver` function. | ||
* | ||
* Use "interface merging" to mark your class as observable: | ||
* | ||
* class Foo {} | ||
* interface Foo extends FluidObservable<FooEvent> {} | ||
* | ||
* Once that's done, you get the following benefits: | ||
* - observers added with `addFluidObserver` are type-checked | ||
* - events passed to `callFluidObservers` are type-checked | ||
*/ | ||
export interface FluidObservable<E extends FluidEvent = any> { | ||
// Never access this directly. Its only purpose is to enforce type safety. | ||
[$observers]?: E | null | ||
} | ||
/** | ||
* Extend this class for automatic TypeScript support when passing | ||
* an object to a `fluids` compatible function. | ||
* `FluidValue` objects can be unwrapped with `getFluidValue` to access | ||
* their current value. | ||
* | ||
* Libraries may support observable values by handling `FluidValue` objects | ||
* in their functions and classes. | ||
*/ | ||
abstract class FluidValue< | ||
T = any, | ||
E extends FluidEvent<T> = UnknownFluidEvent<T> | ||
> { | ||
protected [$get]: () => T | ||
protected [$observers]?: Set<FluidObserver<E>> | ||
abstract class FluidValue<T = any> { | ||
constructor(get?: () => T) { | ||
@@ -124,6 +133,6 @@ if (!get && !(get = this.get)) { | ||
/** Called after an observer is added. */ | ||
protected observerAdded?(count: number, observer: FluidObserver): void | ||
protected observerAdded?(count: number, observer: FluidObserver<any>): void | ||
/** Called after an observer is removed. */ | ||
protected observerRemoved?(count: number, observer: FluidObserver): void | ||
protected observerRemoved?(count: number, observer: FluidObserver<any>): void | ||
} | ||
@@ -151,4 +160,4 @@ | ||
/** Observe a `fluids`-compatible object. */ | ||
function addFluidObserver<T, E extends FluidEvent>( | ||
target: FluidValue<T, E>, | ||
function addFluidObserver<E extends FluidEvent>( | ||
target: FluidObservable<E>, | ||
observer: FluidObserver<E> | ||
@@ -163,13 +172,11 @@ ): typeof observer | ||
function addFluidObserver(target: any, observer: FluidObserver) { | ||
if (target[$get]) { | ||
let observers: Set<FluidObserver> = target[$observers] | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())) | ||
let observers: Set<FluidObserver> = target[$observers] | ||
if (!observers) { | ||
setHidden(target, $observers, (observers = new Set())) | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer) | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer) | ||
} | ||
if (!observers.has(observer)) { | ||
observers.add(observer) | ||
if (target.observerAdded) { | ||
target.observerAdded(observers.size, observer) | ||
} | ||
} | ||
} | ||
@@ -181,3 +188,3 @@ return observer | ||
function removeFluidObserver<E extends FluidEvent>( | ||
target: FluidValue<any, E>, | ||
target: FluidObservable<E>, | ||
observer: FluidObserver<E> | ||
@@ -184,0 +191,0 @@ ): void |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28876
542
146