fluidstate
Advanced tools
Comparing version 0.0.5 to 0.0.8
@@ -7,3 +7,2 @@ import { Configuration } from "./types"; | ||
get: <T_2>(node: import("./types").Node<T_2>) => T_2; | ||
batch: (update: () => void) => void; | ||
configure: (newConfiguration: Partial<Configuration>) => void; | ||
@@ -17,2 +16,6 @@ createCustomObserved: <T_3>(inert: import("./types").InertControl<T_3>) => import("./types").Observed<T_3>; | ||
disableComputed: (node: import("./types").Computed<unknown>) => void; | ||
batch: (update: () => void) => void; | ||
triggerUpdate: ({ shouldResolveImmediatelyAfterBatch, }?: { | ||
shouldResolveImmediatelyAfterBatch?: boolean | undefined; | ||
}) => void; | ||
}; |
@@ -35,3 +35,2 @@ "use strict"; | ||
get, | ||
batch: updateManager.batch, | ||
configure, | ||
@@ -44,3 +43,5 @@ createCustomObserved, | ||
createEffect, | ||
disableComputed: dependenciesManager.disableComputed | ||
disableComputed: dependenciesManager.disableComputed, | ||
batch: updateManager.batch, | ||
triggerUpdate: updateManager.triggerUpdate | ||
}; | ||
@@ -47,0 +48,0 @@ }; |
@@ -7,3 +7,2 @@ import { createApi } from "./api"; | ||
get: <T_2>(node: import("./types").Node<T_2>) => T_2; | ||
batch: (update: () => void) => void; | ||
configure: (newConfiguration: Partial<import("./types").Configuration>) => void; | ||
@@ -17,2 +16,6 @@ createCustomObserved: <T_3>(inert: import("./types").InertControl<T_3>) => import("./types").Observed<T_3>; | ||
disableComputed: (node: import("./types").Computed<unknown>) => void; | ||
batch: (update: () => void) => void; | ||
triggerUpdate: ({ shouldResolveImmediatelyAfterBatch, }?: { | ||
shouldResolveImmediatelyAfterBatch?: boolean | undefined; | ||
}) => void; | ||
}; | ||
@@ -26,6 +29,56 @@ declare const defaultReactiveApi: { | ||
}; | ||
declare const configure: (newConfiguration: Partial<import("./types").Configuration>) => void, batch: (update: () => void) => void; | ||
declare const configure: (newConfiguration: Partial<import("./types").Configuration>) => void, batch: (update: () => void) => void, triggerUpdate: ({ shouldResolveImmediatelyAfterBatch, }?: { | ||
shouldResolveImmediatelyAfterBatch?: boolean | undefined; | ||
}) => void; | ||
declare const createEffect: import("./types").CreateEffect, createReactive: <T>(something: T) => T, getInert: <T extends object>(proxy: T) => T | null, getReactive: <T extends object>(something: T) => T | null, getComputedKeys: <T>(object: T) => Set<string | symbol>; | ||
export { createApi, createReactiveApi }; | ||
export { defaultApi, defaultReactiveApi }; | ||
export { configure, batch, createEffect, createReactive, getInert, getReactive, getComputedKeys, }; | ||
export { | ||
/** | ||
* Configure default behavior of `fluidstate` | ||
*/ | ||
configure, | ||
/** | ||
* Given a function, run it, while preventing recalculations and effects until | ||
* the function finished running | ||
*/ | ||
batch, | ||
/** | ||
* Triggers an update to all computed properties and runs effects. If called | ||
* during batching, update will happen after the batch is finished (or ignored | ||
* if the option is overriden). Update triggering will also be ignored in case | ||
* a current update is already in progress | ||
*/ | ||
triggerUpdate, | ||
/** | ||
* Create a reactive effect, consisting of reactive and inert parts. Reactive | ||
* part subscribes to all properties that are accessed in it or are returned. | ||
* Inert part takes the value returned from reactive part and can safely | ||
* perform any effect - property access in the inert part will not trigger | ||
* any subscriptions | ||
*/ | ||
createEffect, | ||
/** | ||
* Creates a reactive wrapper (proxy) around any object. Arrays, sets, maps and | ||
* regular objects are natively supported. Effects / computed properties that access | ||
* items of these objects (such as keys, values, etc) automaticlaly subscribe to | ||
* them. The reactive wrapper does not create a clone of the object - the original | ||
* object is still used for all storage and is changed as changes are made to the | ||
* reactive wrapper | ||
*/ | ||
createReactive, | ||
/** | ||
* Given a reactive object / wrapper / proxy, return its original inert object | ||
*/ | ||
getInert, | ||
/** | ||
* Given an inert object that has a reactive wrapper / proxy, return its reactive | ||
* wrapper / proxy. If the object doesn't have the reactive wrapper / proxy, | ||
* null is returned | ||
*/ | ||
getReactive, | ||
/** | ||
* Given an object, get its computed keys. If a non-reactive object is provided, | ||
* get keys that would become computed if object was to become reactive | ||
*/ | ||
getComputedKeys, }; |
@@ -20,3 +20,3 @@ "use strict"; | ||
}); | ||
exports.getReactive = exports.getInert = exports.getComputedKeys = exports.defaultReactiveApi = exports.defaultApi = void 0; | ||
exports.triggerUpdate = exports.getReactive = exports.getInert = exports.getComputedKeys = exports.defaultReactiveApi = exports.defaultApi = void 0; | ||
var _api = require("./api"); | ||
@@ -30,4 +30,6 @@ var _reactiveApi = require("./reactive-api"); | ||
configure, | ||
batch | ||
batch, | ||
triggerUpdate | ||
} = defaultApi; | ||
exports.triggerUpdate = triggerUpdate; | ||
exports.batch = batch; | ||
@@ -34,0 +36,0 @@ exports.configure = configure; |
{ | ||
"name": "fluidstate", | ||
"version": "0.0.5", | ||
"version": "0.0.8", | ||
"description": "Library for fine-grained reactivity state management", | ||
@@ -5,0 +5,0 @@ "repository": "https://gitlab.com/fluidstate/fluidstate", |
@@ -27,8 +27,2 @@ "use strict"; | ||
}; | ||
/** | ||
* Given an inert object that has a reactive wrapper / proxy, return its reactive | ||
* wrapper / proxy. If the object doesn't have the reactive wrapper / proxy, | ||
* null is returned | ||
*/ | ||
const getReactive = something => { | ||
@@ -45,6 +39,2 @@ if (isProxySet.has(something)) { | ||
}; | ||
/** | ||
* Given a reactive object / wrapper / proxy, return its original inert object | ||
*/ | ||
const getInert = proxy => { | ||
@@ -56,11 +46,2 @@ return proxyInertMap.get(proxy) ?? null; | ||
}; | ||
/** | ||
* Creates a reactive wrapper (proxy) around any object. Arrays, sets, maps and | ||
* regular objects are natively supported. Effects / computed properties that access | ||
* items of these objects (such as keys, values, etc) automaticlaly subscribe to | ||
* them. The reactive wrapper does not create a clone of the object - the original | ||
* object is still used for all storage and is changed as changes are made to the | ||
* reactive wrapper | ||
*/ | ||
const createReactive = something => { | ||
@@ -110,10 +91,2 @@ if ((0, _reactiveUtils.isObject)(something)) { | ||
}; | ||
/** | ||
* Create a reactive effect, consisting of reactive and inert parts. Reactive | ||
* part subscribes to all properties that are accessed in it or are returned. | ||
* Inert part takes the value returned from reactive part and can safely | ||
* perform any effect - property access in the inert part will not trigger | ||
* any subscriptions | ||
*/ | ||
const createEffect = (calculate, perform) => { | ||
@@ -126,7 +99,2 @@ return api.createEffect(() => { | ||
}; | ||
/** | ||
* Given an object, get its computed keys. If a non-reactive object is provided, | ||
* get keys that would become computed if object was to become reactive | ||
*/ | ||
const getComputedKeys = object => { | ||
@@ -133,0 +101,0 @@ if ((0, _reactiveUtils.isObject)(object) && !Array.isArray(object) && !(object instanceof Set) && !(object instanceof Map)) { |
@@ -12,2 +12,5 @@ import { DependenciesManager } from "./dependencies-manager"; | ||
cancelEffect: (effectId: object) => void; | ||
triggerUpdate: ({ shouldResolveImmediatelyAfterBatch, }?: { | ||
shouldResolveImmediatelyAfterBatch?: boolean | undefined; | ||
}) => void; | ||
}; |
@@ -9,3 +9,6 @@ "use strict"; | ||
var _singleUpdateManager = require("./single-update-manager"); | ||
const createNodeUpdateManager = (cancelScheduledUpdate, performEffects, dependenciesManager) => { | ||
const defaultGetTriggerUpdateOptions = { | ||
shouldResolveImmediatelyAfterBatch: false | ||
}; | ||
const createNodeUpdateManager = (isCurrentlyBatching, setTriggerUpdateIntent, cancelScheduledUpdate, performEffects, dependenciesManager) => { | ||
let scheduledUpdates = []; | ||
@@ -30,3 +33,27 @@ let currentUpdateIndex = -1; | ||
}; | ||
const triggerUpdate = () => { | ||
const triggerUpdate = ({ | ||
shouldResolveImmediatelyAfterBatch = true | ||
} = {}) => { | ||
// Because update triggering is exposed to the user, there may be | ||
// a situation where the update gets triggered during the current | ||
// update. If allowed, that would lead to duplicated updates | ||
if (isUpdateInProgress()) { | ||
return; | ||
} | ||
// Batching is incompatible with update triggering. If update is | ||
// triggered during batching, we will defer it until after batching | ||
// finishes | ||
if (isCurrentlyBatching()) { | ||
// Users may alter behavior such that update is not triggered | ||
// immediately after batch finishes. That's also the case during | ||
// outside ".get()" call, since it's not useful to have it triggered | ||
// immediately after batching in that case. The default behavior, | ||
// however, is to speed up the update after the batch finishes | ||
if (shouldResolveImmediatelyAfterBatch) { | ||
setTriggerUpdateIntent(); | ||
} | ||
return; | ||
} | ||
// If we call triggerUpdate() after the update was | ||
@@ -89,3 +116,4 @@ // already scheduled, we should cancel the update and | ||
}; | ||
const createBatchManager = (isNodeAddedToSchedule, scheduleNextUpdate) => { | ||
const createBatchManager = (isNodeAddedToSchedule, triggerUpdate, scheduleNextUpdate) => { | ||
let hasTriggerUpdateIntent = false; | ||
const isCurrentlyBatching = () => batchingCount > 0; | ||
@@ -100,9 +128,18 @@ let batchingCount = 0; | ||
if (!isCurrentlyBatching() && isNodeAddedToSchedule()) { | ||
scheduleNextUpdate(); | ||
if (hasTriggerUpdateIntent) { | ||
hasTriggerUpdateIntent = false; | ||
triggerUpdate(); | ||
} else { | ||
scheduleNextUpdate(); | ||
} | ||
} | ||
} | ||
}; | ||
const setTriggerUpdateIntent = () => { | ||
hasTriggerUpdateIntent = true; | ||
}; | ||
return { | ||
isCurrentlyBatching, | ||
batch | ||
batch, | ||
setTriggerUpdateIntent | ||
}; | ||
@@ -166,5 +203,3 @@ }; | ||
// the update, since a dependency might have changed. | ||
if (!isUpdateInProgress() && !isCurrentlyBatching()) { | ||
triggerUpdate(); | ||
} | ||
triggerUpdate(defaultGetTriggerUpdateOptions); | ||
nodeCollector.collect(node); | ||
@@ -179,4 +214,5 @@ return node.inert.get(); | ||
isCurrentlyBatching, | ||
batch | ||
} = createBatchManager(() => isNodeAddedToSchedule(), scheduleNextUpdate); | ||
batch, | ||
setTriggerUpdateIntent | ||
} = createBatchManager(() => isNodeAddedToSchedule(), () => triggerUpdate(), scheduleNextUpdate); | ||
const scheduleUpdate = node => { | ||
@@ -198,3 +234,3 @@ addNodeToSchedule(node); | ||
triggerUpdate | ||
} = createNodeUpdateManager(cancelScheduledUpdate, performEffects, dependenciesManager); | ||
} = createNodeUpdateManager(isCurrentlyBatching, setTriggerUpdateIntent, cancelScheduledUpdate, performEffects, dependenciesManager); | ||
return { | ||
@@ -206,3 +242,4 @@ set, | ||
addEffect, | ||
cancelEffect | ||
cancelEffect, | ||
triggerUpdate | ||
}; | ||
@@ -209,0 +246,0 @@ }; |
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
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
203171
2022