🧰 Essentials | Package exports - traced-fabric/core GitHub Wiki
📜 Table of contents
🛠️ Basic functions
traceFabric(...)
🔧 Track the mutation of a given JSON-like object or array. Other tracedFabric
can be nested inside.
The trace
(array of mutations
), that is produced by the tracedFabric
on values mutation, can be used to apply them to other objects or arrays, using the applyTrace(...)
function.
Arguments
- value - an object or array that will be deeply tracked. Value is JSON.stringify safe. The type of the value should be the same as JSONStructure.
- onMutation optional - a function that is triggered when the
traced
value is mutated. The function receives themutation
as an argument and should return themutation
to be saved to thetrace
. If no modification is needed, return the original mutation; otherwise, return the modified mutation for storage.
Returns
Object with the following properties:
- value - the
traced
proxy of the given value. - trace - the array of
mutations
that are made to the value. - clearTrace - a function that clears the trace.
Example
const bestDays = traceFabric([2, 7, 16]);
const fabric = traceFabric({
season: 'winter',
bestDays: bestDays.value,
});
fabric.value.season = 'summer';
fabric.value.bestDays.push(25);
bestDays.value.push(26);
console.log(fabric.trace);
// [{
// mutated: 'object', type: 'set',
// targetChain: ['season'],
// value: 'summer',
// }, {
// mutated: 'array', type: 'set',
// targetChain: ['bestDays', 3],
// value: 25,
// }, {
// mutated: 'array', type: 'set',
// targetChain: ['bestDays', 4],
// value: 26,
// }]
With the custom onMutation
function, that adds a timestamp to the mutation.
const bestDays = traceFabric([2, 7, 16]);
const fabric = traceFabric({
season: 'winter',
bestDays: bestDays.value,
}, mutation => ({
...mutation,
timestamp: Date.now(),
}));
fabric.value.season = 'summer';
fabric.value.bestDays.push(25);
bestDays.value.push(26);
console.log(fabric.trace);
// [{
// mutated: 'object',
// targetChain: ['season'],
// value: 'summer',
// type: 'set',
// timestamp: 1725368703427,
// }, {
// mutated: 'array',
// targetChain: ['bestDays', 3],
// value: 25,
// type: 'set',
// timestamp: 1725368703428,
// }, {
// mutated: 'array',
// targetChain: ['bestDays', 4],
// value: 26,
// type: 'set',
// timestamp: 1725368703428,
// }]
applyTrace(...)
🔧 Applies tracedFabric
mutations
to the given value. The value should have the same state as the traceFabric
value before allied mutations.
[!WARNING] This function mutates the value directly.
Arguments
- value - the object to which the trace will be directly applied.
- trace - the
trace
(array ofmutations
) to apply to the given value.
Example
const fabric = traceFabric({
season: 'winter',
besetDays: [12, 15, 17],
});
const target = {
season: 'winter',
besetDays: [12, 15, 17],
};
target.season = 'summer';
target.besetDays.push(20);
applyTrace(target, fabric.trace);
console.log(target);
// {
// season: "summer",
// besetDays: [ 12, 15, 17, 20 ],
// }
deepClone(...)
🔧 Deep clone an object or array.
Primarily used to clone tracedFabric
and tracedValues
without inheriting proxy traps, and potentially breaking tracedFabric.
[!NOTE]
deepClone(...)
will not copy symbols
Arguments
- value - The value to clone
Returns
The cloned value
Example
const fabric = traceFabric({ season: 'winter', bestDays: [2, 7, 16] });
const clone = deepClone(fabric.value);
console.log(clone); // { season: 'winter', bestDays: [2, 7, 16] }
console.log(clone === fabric.value); // false
console.log(clone.bestDays === fabric.value.bestDays); // false
🛠️ Utility functions
isStructure(...)
🪛 Checks if the value is a typeof object
and not null
.
Arguments
- value - value that needs to be checked
Returns
Boolean
Example
console.log(isStructure({ hello: 'world' })); // true
console.log(isStructure(['hello', 'world'])); // true
console.log(isStructure(1)); // false
console.log(isStructure(true)); // false
console.log(isStructure('hello')); // false
console.log(isStructure(null)); // false
console.log(isStructure(undefined)); // false
console.log(isStructure(true)); // false
isTracedFabric(...)
🪛 Checks if the given value is a tracedFabric
.
To check the definition of tracedFabric
, see Wiki - 📜 Naming
Arguments
- value - value that needs to be checked
Returns
Boolean
Example
const traced = traceFabric({ // --> tracedFabric AND traced
innerArray: [1, 2, 3], // --> tracedValue AND traced
});
console.log(isTracedFabric(traced.value)); // true
console.log(isTracedFabric(traced.value.innerArray)); // false
isTracedValue(...)
🪛 Checks if the given value is a tracedValue
.
To check the definition of tracedValue
, see Wiki - 📜 Naming
Arguments
- value - value that needs to be checked
Returns
Boolean
Example
const traced = traceFabric({ // --> tracedFabric AND traced
innerArray: [1, 2, 3], // --> tracedValue AND traced
});
console.log(isTracedValue(traced.value)); // false
console.log(isTracedValue(traced.value.innerArray)); // true
isTraced(...)
🪛 Checks if the given value is a traced
.
To check the definition of traced
, see Wiki - 📜 Naming
Arguments
- value - value that needs to be checked
Returns
Boolean
Example
const traced = traceFabric({ // --> tracedFabric AND traced
innerArray: [1, 2, 3], // --> tracedValue AND traced
});
console.log(isTraced(traced.value)); // true
console.log(isTraced(traced.value.innerArray)); // true
withoutTracing(...)
🪛 Ignores recording of all mutations
to trace
in the given function.
The function should not be async, as it turns off the tracing globally.
[!WARNING] Use with caution, as it can lead to breaking
applyTrace
function, because of the missing mutations.
Arguments
- callback - function in which
tracing
is disabled
Returns
Same as the return value of the given function
Example
const fabric = traceFabric({ season: 'winter' });
fabric.value.season = 'spring'; // adds mutation to the traceLogs
withoutTracing(() => {
fabric.value.season = 'summer'; // no mutation is added to the traceLogs
});
console.log(fabric.trace);
// [{
// mutated: "object",
// targetChain: [ "season" ],
// value: "spring",
// type: "set",
// }]
isTracing(...)
🪛 Check if tracing is enabled.
If the tracing is enabled, the mutations
are recorded in the trace
.
Returns
Boolean
Example
console.log(isTracing()); // true
withoutTracing(() => {
console.log(isTracing()); // false
});
🛠️ Miscellaneous
removeTraceSubscription(...)
🪛 Will unsubscribe the receiver
from the sender
. So after mutating the sender
, the receiver
will not receive any updates.
Needs to be used to speed up garbage collection.
Arguments
- changesSender - the
sender
of the updates (value that is a part of the receiver). - changesReceiver -
receiver
of the updates.
Same as the return value of the given function
Example
const globalMessages = traceFabric(['Welcome!']);
function userLifecycle(): void {
const user = traceFabric({
globalMessages: globalMessages.value,
});
// The `globalMessages` subscribes to the `user` value to send updates.
// To speed up the gc, remove the subscription, at the end of the `user` lifecycle.
removeTraceSubscription(globalMessages.value, user.value);
}