Comparing version 0.1.1 to 0.1.2
{ | ||
"name": "fluids", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "Glue layer for reactivity", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -8,1 +8,76 @@ # fluids | ||
- Be as tiny as possible | ||
## API | ||
- `hasFluidValue(any)`: Returns true if the given value is a fluid object | ||
- `getFluidValue(any)`: Returns the current value of the fluid object (if possible), otherwise the argument is passed thru | ||
- `getFluidConfig(any)`: Returns the `FluidConfig` object that allows for observing the argument | ||
- `setFluidConfig(object, FluidConfig)`: Defines the hidden property that holds the `FluidConfig` object. This can only be called once per fluid object. | ||
- `addFluidObserver(object, FluidObserver)`: Attach an observer to a fluid object, and get an unsubscribe function back. Returns undefined if the first argument is not a fluid object. | ||
## `FluidConfig` example | ||
This example adds observability to a ref object (like in React: `{ value }`). | ||
Any object can conform to the `FluidConfig` interface **without needing to change its public API.** | ||
```ts | ||
import { setFluidConfig, FluidObserver, FluidEvent } from 'fluids' | ||
/** Create a `{ value }` object that can be observed */ | ||
function createRef(value) { | ||
const ref = {} | ||
// Observer tracking | ||
const children = new Set<FluidObserver>() | ||
const emit = (event: FluidEvent) => | ||
children.forEach(child => child.onParentChange(event)) | ||
// Change tracking | ||
const get = () => value | ||
Object.defineProperty(ref, 'value', { | ||
enumerable: true, | ||
get, | ||
set: newValue => { | ||
if (value !== newValue) { | ||
value = newValue | ||
emit({ | ||
type: 'change', | ||
parent: ref, | ||
value, | ||
}) | ||
} | ||
} | ||
}) | ||
// Observer API | ||
setFluidConfig(ref, { | ||
get, | ||
addChild: child => children.add(child), | ||
removeChild: child => children.delete(child), | ||
}) | ||
return ref | ||
} | ||
``` | ||
## `FluidObserver` example | ||
This example shows how to observe a fluid object. | ||
```ts | ||
import { addFluidObserver } from 'fluids' | ||
const ref = createRef(0) | ||
const stop = addFluidObserver(ref, { | ||
onParentChange(event) { | ||
if (event.type === 'change') { | ||
console.log(event.value, event.parent) | ||
} | ||
} | ||
}) | ||
ref.value++ | ||
stop() | ||
ref.value++ | ||
``` |
@@ -1,2 +0,2 @@ | ||
export { hasFluidValue, getFluidValue, getFluidConfig, setFluidConfig }; | ||
export { hasFluidValue, getFluidValue, getFluidConfig, setFluidConfig, addFluidObserver, }; | ||
/** Does the given value have a `FluidConfig` object? */ | ||
@@ -7,3 +7,3 @@ declare const hasFluidValue: (arg: any) => arg is FluidValue<any, any>; | ||
declare function getFluidValue<T>(target: T): GetFluidValue<T>; | ||
declare type GetFluidConfig<T> = T extends FluidValue<infer U, infer E> ? FluidConfig<U, E> : undefined; | ||
declare type GetFluidConfig<T> = T extends FluidValue<infer U, infer E> ? FluidConfig<U, E> : FluidConfig | undefined; | ||
/** Get the methods for observing the given object. Returns undefined if not a fluid object. */ | ||
@@ -13,2 +13,4 @@ declare function getFluidConfig<T>(arg: T): GetFluidConfig<T>; | ||
declare function setFluidConfig(target: object, config: FluidConfig): void; | ||
/** Add an observer to a fluid object. Returns an unsubscribe function if the target is a fluid object, otherwise undefined. */ | ||
declare function addFluidObserver(target: object, observer: FluidObserver): (() => void) | undefined; | ||
export interface ChangeEvent<T = any> { | ||
@@ -15,0 +17,0 @@ type: 'change'; |
@@ -22,2 +22,11 @@ "use strict"; | ||
exports.setFluidConfig = setFluidConfig; | ||
/** Add an observer to a fluid object. Returns an unsubscribe function if the target is a fluid object, otherwise undefined. */ | ||
function addFluidObserver(target, observer) { | ||
var config = getFluidConfig(target); | ||
if (config) { | ||
config.addChild(observer); | ||
return function () { return config.removeChild(observer); }; | ||
} | ||
} | ||
exports.addFluidObserver = addFluidObserver; | ||
/** | ||
@@ -24,0 +33,0 @@ * This class stores a single mutable value, which can be observed by a `FluidObserver` object. |
const $config = Symbol.for('FluidValue:config') | ||
export { hasFluidValue, getFluidValue, getFluidConfig, setFluidConfig } | ||
export { | ||
hasFluidValue, | ||
getFluidValue, | ||
getFluidConfig, | ||
setFluidConfig, | ||
addFluidObserver, | ||
} | ||
@@ -19,3 +25,3 @@ /** Does the given value have a `FluidConfig` object? */ | ||
? FluidConfig<U, E> | ||
: undefined | ||
: FluidConfig | undefined | ||
@@ -33,2 +39,11 @@ /** Get the methods for observing the given object. Returns undefined if not a fluid object. */ | ||
/** Add an observer to a fluid object. Returns an unsubscribe function if the target is a fluid object, otherwise undefined. */ | ||
function addFluidObserver(target: object, observer: FluidObserver) { | ||
const config = getFluidConfig(target) | ||
if (config) { | ||
config.addChild(observer) | ||
return () => config!.removeChild(observer) | ||
} | ||
} | ||
export interface ChangeEvent<T = any> { | ||
@@ -35,0 +50,0 @@ type: 'change' |
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
10397
166
83