Skip to content

Commit

Permalink
TEMP: add dist
Browse files Browse the repository at this point in the history
  • Loading branch information
paultsimura committed Jun 19, 2024
1 parent c2e6351 commit 153bc79
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 29 deletions.
12 changes: 11 additions & 1 deletion dist/Onyx.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ function connect(connectOptions) {
// We search all the keys in storage to see if any are a "match" for the subscriber we are connecting so that we
// can send data back to the subscriber. Note that multiple keys can match as a subscriber could either be
// subscribed to a "collection key" or a single key.
const matchingKeys = Array.from(keys).filter((key) => OnyxUtils_1.default.isKeyMatch(mapping.key, key));
const matchingKeys = [];
keys.forEach((key) => {
if (!OnyxUtils_1.default.isKeyMatch(mapping.key, key)) {
return;
}
matchingKeys.push(key);
});
// If the key being connected to does not exist we initialize the value with null. For subscribers that connected
// directly via connect() they will simply get a null value sent to them without any information about which key matched
// since there are none matched. In withOnyx() we wait for all connected keys to return a value before rendering the child
Expand Down Expand Up @@ -560,6 +566,10 @@ function updateSnapshots(data) {
}
updatedData = Object.assign(Object.assign({}, updatedData), { [key]: (0, pick_1.default)(value, Object.keys(snapshotData[key])) });
});
// Skip the update if there's no data to be merged
if (utils_1.default.isEmptyObject(updatedData)) {
return;
}
promises.push(() => merge(snapshotKey, { data: updatedData }));
});
return Promise.all(promises.map((p) => p()));
Expand Down
15 changes: 6 additions & 9 deletions dist/OnyxUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,16 +262,13 @@ function tryGetCachedValue(key, mapping) {
if (allCacheKeys.size === 0) {
return;
}
const matchingKeys = Array.from(allCacheKeys).filter((k) => k.startsWith(key));
const values = matchingKeys.reduce((finalObject, matchedKey) => {
const cachedValue = OnyxCache_1.default.get(matchedKey);
if (cachedValue) {
// This is permissible because we're in the process of constructing the final object in a reduce function.
// eslint-disable-next-line no-param-reassign
finalObject[matchedKey] = cachedValue;
const values = {};
allCacheKeys.forEach((cacheKey) => {
if (!cacheKey.startsWith(key)) {
return;
}
return finalObject;
}, {});
values[cacheKey] = OnyxCache_1.default.get(cacheKey);
});
val = values;
}
if (mapping === null || mapping === void 0 ? void 0 : mapping.selector) {
Expand Down
2 changes: 1 addition & 1 deletion dist/useOnyx.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ type UseOnyxResult<TKey extends OnyxKey, TValue> = [CachedValue<TKey, TValue>, R
declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<TReturnValue> & Required<UseOnyxSelectorOption<TKey, TReturnValue>>): UseOnyxResult<TKey, TReturnValue>;
declare function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(key: TKey, options?: BaseUseOnyxOptions & UseOnyxInitialValueOption<NoInfer<TReturnValue>>): UseOnyxResult<TKey, TReturnValue>;
export default useOnyx;
export type { UseOnyxResult, ResultMetadata, FetchStatus };
export type { FetchStatus, ResultMetadata, UseOnyxResult };
62 changes: 44 additions & 18 deletions dist/useOnyx.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const fast_equals_1 = require("fast-equals");
const react_1 = require("react");
const Onyx_1 = __importDefault(require("./Onyx"));
const OnyxCache_1 = __importDefault(require("./OnyxCache"));
const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
const useLiveRef_1 = __importDefault(require("./useLiveRef"));
const usePrevious_1 = __importDefault(require("./usePrevious"));
const Onyx_1 = __importDefault(require("./Onyx"));
const OnyxCache_1 = __importDefault(require("./OnyxCache"));
function getCachedValue(key, selector) {
var _a;
return ((_a = OnyxUtils_1.default.tryGetCachedValue(key, { selector })) !== null && _a !== void 0 ? _a : undefined);
Expand All @@ -21,7 +21,9 @@ function useOnyx(key, options) {
const selectorRef = (0, useLiveRef_1.default)(options === null || options === void 0 ? void 0 : options.selector);
// Stores the previous cached value as it's necessary to compare with the new value in `getSnapshot()`.
// We initialize it to `null` to simulate that we don't have any value from cache yet.
const cachedValueRef = (0, react_1.useRef)(null);
const previousValueRef = (0, react_1.useRef)(null);
// Stores the newest cached value in order to compare with the previous one and optimize `getSnapshot()` execution.
const newValueRef = (0, react_1.useRef)(null);
// Stores the previously result returned by the hook, containing the data from cache and the fetch status.
// We initialize it to `undefined` and `loading` fetch status to simulate the initial result when the hook is loading from the cache.
// However, if `initWithStoredValues` is `true` we set the fetch status to `loaded` since we want to signal that data is ready.
Expand All @@ -34,6 +36,8 @@ function useOnyx(key, options) {
// Indicates if it's the first Onyx connection of this hook or not, as we don't want certain use cases
// in `getSnapshot()` to be satisfied several times.
const isFirstConnectionRef = (0, react_1.useRef)(true);
// Indicates if we should get the newest cached value from Onyx during `getSnapshot()` execution.
const shouldGetCachedValueRef = (0, react_1.useRef)(true);
(0, react_1.useEffect)(() => {
// These conditions will ensure we can only handle dynamic collection member keys from the same collection.
if (previousKey === key) {
Expand All @@ -52,46 +56,68 @@ function useOnyx(key, options) {
throw new Error(`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`);
}, [previousKey, key]);
const getSnapshot = (0, react_1.useCallback)(() => {
var _a, _b;
// We get the value from the cache, supplying a selector too in case it's defined.
// If `newValue` is `undefined` it means that the cache doesn't have a value for that key yet.
// If `newValue` is `null` or any other value it means that the cache does have a value for that key.
// This difference between `undefined` and other values is crucial and it's used to address the following
// conditions and use cases.
let newValue = getCachedValue(key, selectorRef.current);
var _a, _b, _c;
// We get the value from cache while the first connection to Onyx is being made,
// so we can return any cached value right away. After the connection is made, we only
// update `newValueRef` when `Onyx.connect()` callback is fired.
if (isFirstConnectionRef.current || shouldGetCachedValueRef.current) {
// If `newValueRef.current` is `undefined` it means that the cache doesn't have a value for that key yet.
// If `newValueRef.current` is `null` or any other value it means that the cache does have a value for that key.
// This difference between `undefined` and other values is crucial and it's used to address the following
// conditions and use cases.
newValueRef.current = getCachedValue(key, selectorRef.current);
// We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshot()` is executed,
// and only when `Onyx.connect()` callback is fired.
shouldGetCachedValueRef.current = false;
}
const hasCacheForKey = OnyxCache_1.default.hasCacheForKey(key);
// Since the fetch status can be different given the use cases below, we define the variable right away.
let newFetchStatus;
// If we have pending merge operations for the key during the first connection, we set the new value to `undefined`
// and fetch status to `loading` to simulate that it is still being loaded until we have the most updated data.
// If `allowStaleData` is `true` this logic will be ignored and cached value will be used, even if it's stale data.
if (isFirstConnectionRef.current && OnyxUtils_1.default.hasPendingMergeForKey(key) && !(options === null || options === void 0 ? void 0 : options.allowStaleData)) {
newValue = undefined;
newValueRef.current = undefined;
newFetchStatus = 'loading';
}
// If data is not present in cache and `initialValue` is set during the first connection,
// we set the new value to `initialValue` and fetch status to `loaded` since we already have some data to return to the consumer.
if (isFirstConnectionRef.current && !hasCacheForKey && (options === null || options === void 0 ? void 0 : options.initialValue) !== undefined) {
newValue = ((_a = options === null || options === void 0 ? void 0 : options.initialValue) !== null && _a !== void 0 ? _a : undefined);
newValueRef.current = ((_a = options === null || options === void 0 ? void 0 : options.initialValue) !== null && _a !== void 0 ? _a : undefined);
newFetchStatus = 'loaded';
}
// We do a deep equality check if we are subscribed to a collection key and `selector` is defined,
// since each `OnyxUtils.tryGetCachedValue()` call will generate a plain new collection object with new records as well,
// all of them created using the `selector` function.
// For the other cases we will only deal with object reference checks, so just a shallow equality check is enough.
let areValuesEqual;
if (OnyxUtils_1.default.isCollectionKey(key) && selectorRef.current) {
areValuesEqual = (0, fast_equals_1.deepEqual)((_b = previousValueRef.current) !== null && _b !== void 0 ? _b : undefined, newValueRef.current);
}
else {
areValuesEqual = (0, fast_equals_1.shallowEqual)((_c = previousValueRef.current) !== null && _c !== void 0 ? _c : undefined, newValueRef.current);
}
// If the previously cached value is different from the new value, we update both cached value
// and the result to be returned by the hook.
// If the cache was set for the first time, we also update the cached value and the result.
const isCacheSetFirstTime = cachedValueRef.current === null && hasCacheForKey;
if (isCacheSetFirstTime || !(0, fast_equals_1.deepEqual)((_b = cachedValueRef.current) !== null && _b !== void 0 ? _b : undefined, newValue)) {
cachedValueRef.current = newValue;
resultRef.current = [cachedValueRef.current, { status: newFetchStatus !== null && newFetchStatus !== void 0 ? newFetchStatus : 'loaded' }];
const isCacheSetFirstTime = previousValueRef.current === null && hasCacheForKey;
if (isCacheSetFirstTime || !areValuesEqual) {
previousValueRef.current = newValueRef.current;
// If the new value is `null` we default it to `undefined` to ensure the consumer gets a consistent result from the hook.
resultRef.current = [previousValueRef.current, { status: newFetchStatus !== null && newFetchStatus !== void 0 ? newFetchStatus : 'loaded' }];
}
return resultRef.current;
}, [key, selectorRef, options === null || options === void 0 ? void 0 : options.allowStaleData, options === null || options === void 0 ? void 0 : options.initialValue]);
const subscribe = (0, react_1.useCallback)((onStoreChange) => {
connectionIDRef.current = Onyx_1.default.connect({
key,
callback: () => {
// We don't need to update the Onyx cache again here, when `callback` is called the cache is already
// expected to be updated, so we just signal that the store changed and `getSnapshot()` can be called again.
// Signals that the first connection was made, so some logics in `getSnapshot()`
// won't be executed anymore.
isFirstConnectionRef.current = false;
// Signals that we want to get the newest cached value again in `getSnapshot()`.
shouldGetCachedValueRef.current = true;
// Finally, we signal that the store changed, making `getSnapshot()` be called again.
onStoreChange();
},
initWithStoredValues: options === null || options === void 0 ? void 0 : options.initWithStoredValues,
Expand Down

0 comments on commit 153bc79

Please sign in to comment.