Remove flux dependency (#10313)
This commit is contained in:
parent
2631b63d13
commit
bee4759208
10 changed files with 231 additions and 109 deletions
|
@ -80,7 +80,6 @@
|
|||
"escape-html": "^1.0.3",
|
||||
"file-saver": "^2.0.5",
|
||||
"filesize": "10.0.6",
|
||||
"flux": "4.0.3",
|
||||
"focus-visible": "^5.2.0",
|
||||
"gfm.css": "^1.1.2",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
|
@ -153,7 +152,6 @@
|
|||
"@types/diff-match-patch": "^1.0.32",
|
||||
"@types/escape-html": "^1.0.1",
|
||||
"@types/file-saver": "^2.0.3",
|
||||
"@types/flux": "^3.1.9",
|
||||
"@types/fs-extra": "^11.0.0",
|
||||
"@types/geojson": "^7946.0.8",
|
||||
"@types/glob-to-regexp": "^0.4.1",
|
||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
|||
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import classNames from "classnames";
|
||||
import { Dispatcher } from "flux";
|
||||
import { Enable, Resizable } from "re-resizable";
|
||||
import { Direction } from "re-resizable/lib/resizer";
|
||||
import * as React from "react";
|
||||
|
@ -28,7 +27,7 @@ import { polyfillTouchEvent } from "../../../@types/polyfill";
|
|||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||
import { RovingAccessibleButton, RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import defaultDispatcher, { MatrixDispatcher } from "../../../dispatcher/dispatcher";
|
||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||
|
@ -68,7 +67,7 @@ polyfillTouchEvent();
|
|||
|
||||
export interface IAuxButtonProps {
|
||||
tabIndex: number;
|
||||
dispatcher?: Dispatcher<ActionPayload>;
|
||||
dispatcher?: MatrixDispatcher;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -16,15 +16,133 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Dispatcher } from "flux";
|
||||
|
||||
import { Action } from "./actions";
|
||||
import { ActionPayload, AsyncActionPayload } from "./payloads";
|
||||
|
||||
type DispatchToken = string;
|
||||
|
||||
function invariant(cond: any, error: string): void {
|
||||
if (!cond) throw new Error(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* A dispatcher for ActionPayloads (the default within the SDK).
|
||||
* Based on the old Flux dispatcher https://github.com/facebook/flux/blob/main/src/Dispatcher.js
|
||||
*/
|
||||
export class MatrixDispatcher extends Dispatcher<ActionPayload> {
|
||||
export class MatrixDispatcher {
|
||||
private readonly callbacks = new Map<DispatchToken, (payload: ActionPayload) => void>();
|
||||
private readonly isHandled = new Map<DispatchToken, boolean>();
|
||||
private readonly isPending = new Map<DispatchToken, boolean>();
|
||||
private pendingPayload?: ActionPayload;
|
||||
private lastId = 1;
|
||||
|
||||
/**
|
||||
* Registers a callback to be invoked with every dispatched payload. Returns
|
||||
* a token that can be used with `waitFor()`.
|
||||
*/
|
||||
public register(callback: (payload: ActionPayload) => void): DispatchToken {
|
||||
const id = "ID_" + this.lastId++;
|
||||
this.callbacks.set(id, callback);
|
||||
if (this.isDispatching()) {
|
||||
// If there is a dispatch happening right now then the newly registered callback should be skipped
|
||||
this.isPending.set(id, true);
|
||||
this.isHandled.set(id, true);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a callback based on its token.
|
||||
*/
|
||||
public unregister(id: DispatchToken): void {
|
||||
invariant(this.callbacks.has(id), `Dispatcher.unregister(...): '${id}' does not map to a registered callback.`);
|
||||
this.callbacks.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the callbacks specified to be invoked before continuing execution
|
||||
* of the current callback. This method should only be used by a callback in
|
||||
* response to a dispatched payload.
|
||||
*/
|
||||
public waitFor(ids: DispatchToken[]): void {
|
||||
invariant(this.isDispatching(), "Dispatcher.waitFor(...): Must be invoked while dispatching.");
|
||||
for (const id of ids) {
|
||||
if (this.isPending.get(id)) {
|
||||
invariant(
|
||||
this.isHandled.get(id),
|
||||
`Dispatcher.waitFor(...): Circular dependency detected while waiting for '${id}'.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
invariant(
|
||||
this.callbacks.get(id),
|
||||
`Dispatcher.waitFor(...): '${id}' does not map to a registered callback.`,
|
||||
);
|
||||
this.invokeCallback(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a payload to all registered callbacks.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
private _dispatch = (payload: ActionPayload): void => {
|
||||
invariant(!this.isDispatching(), "Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.");
|
||||
this.startDispatching(payload);
|
||||
try {
|
||||
for (const [id] of this.callbacks) {
|
||||
if (this.isPending.get(id)) {
|
||||
continue;
|
||||
}
|
||||
this.invokeCallback(id);
|
||||
}
|
||||
} finally {
|
||||
this.stopDispatching();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Is this Dispatcher currently dispatching.
|
||||
*/
|
||||
public isDispatching(): boolean {
|
||||
return !!this.pendingPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the callback stored with the given id. Also do some internal
|
||||
* bookkeeping.
|
||||
*
|
||||
* Must only be called with an id which has a callback and pendingPayload set
|
||||
* @internal
|
||||
*/
|
||||
private invokeCallback(id: DispatchToken): void {
|
||||
this.isPending.set(id, true);
|
||||
this.callbacks.get(id)!(this.pendingPayload!);
|
||||
this.isHandled.set(id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up bookkeeping needed when dispatching.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
private startDispatching(payload: ActionPayload): void {
|
||||
for (const [id] of this.callbacks) {
|
||||
this.isPending.set(id, false);
|
||||
this.isHandled.set(id, false);
|
||||
}
|
||||
this.pendingPayload = payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear bookkeeping used for dispatching.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
private stopDispatching(): void {
|
||||
this.pendingPayload = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an event on the dispatcher's event bus.
|
||||
* @param {ActionPayload} payload Required. The payload to dispatch.
|
||||
|
@ -42,14 +160,14 @@ export class MatrixDispatcher extends Dispatcher<ActionPayload> {
|
|||
}
|
||||
|
||||
if (sync) {
|
||||
super.dispatch(payload);
|
||||
this._dispatch(payload);
|
||||
} else {
|
||||
// Unless the caller explicitly asked for us to dispatch synchronously,
|
||||
// we always set a timeout to do this: The flux dispatcher complains
|
||||
// if you dispatch from within a dispatch, so rather than action
|
||||
// handlers having to worry about not calling anything that might
|
||||
// then dispatch, we just do dispatches asynchronously.
|
||||
window.setTimeout(super.dispatch.bind(this, payload), 0);
|
||||
window.setTimeout(this._dispatch, 0, payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,15 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Dispatcher } from "flux";
|
||||
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
|
||||
// Hook to simplify listening to flux dispatches
|
||||
export const useDispatcher = (
|
||||
dispatcher: Dispatcher<ActionPayload>,
|
||||
handler: (payload: ActionPayload) => void,
|
||||
): void => {
|
||||
// Hook to simplify listening to event dispatches
|
||||
export const useDispatcher = (dispatcher: MatrixDispatcher, handler: (payload: ActionPayload) => void): void => {
|
||||
// Create a ref that stores handler
|
||||
const savedHandler = useRef((payload: ActionPayload) => {});
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
import { EventEmitter } from "events";
|
||||
import AwaitLock from "await-lock";
|
||||
import { Dispatcher } from "flux";
|
||||
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
|
||||
/**
|
||||
* The event/channel to listen for in an AsyncStore.
|
||||
|
@ -52,7 +52,7 @@ export abstract class AsyncStore<T extends Object> extends EventEmitter {
|
|||
* @param {Dispatcher<ActionPayload>} dispatcher The dispatcher to rely upon.
|
||||
* @param {T} initialState The initial state for the store.
|
||||
*/
|
||||
protected constructor(private dispatcher: Dispatcher<ActionPayload>, initialState: T = <T>{}) {
|
||||
protected constructor(private dispatcher: MatrixDispatcher, initialState: T = <T>{}) {
|
||||
super();
|
||||
|
||||
this.dispatcherRef = dispatcher.register(this.onDispatch.bind(this));
|
||||
|
|
|
@ -15,16 +15,16 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { Dispatcher } from "flux";
|
||||
|
||||
import { AsyncStore } from "./AsyncStore";
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { ReadyWatchingStore } from "./ReadyWatchingStore";
|
||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
|
||||
export abstract class AsyncStoreWithClient<T extends Object> extends AsyncStore<T> {
|
||||
protected readyStore: ReadyWatchingStore;
|
||||
|
||||
protected constructor(dispatcher: Dispatcher<ActionPayload>, initialState: T = <T>{}) {
|
||||
protected constructor(dispatcher: MatrixDispatcher, initialState: T = <T>{}) {
|
||||
super(dispatcher, initialState);
|
||||
|
||||
// Create an anonymous class to avoid code duplication
|
||||
|
|
|
@ -14,12 +14,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Store } from "flux/utils";
|
||||
|
||||
import { Action } from "../dispatcher/actions";
|
||||
import dis from "../dispatcher/dispatcher";
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { DoAfterSyncPreparedPayload } from "../dispatcher/payloads/DoAfterSyncPreparedPayload";
|
||||
import { AsyncStore } from "./AsyncStore";
|
||||
|
||||
interface IState {
|
||||
deferredAction: ActionPayload | null;
|
||||
|
@ -30,32 +29,24 @@ const INITIAL_STATE: IState = {
|
|||
};
|
||||
|
||||
/**
|
||||
* A class for storing application state to do with authentication. This is a simple flux
|
||||
* A class for storing application state to do with authentication. This is a simple
|
||||
* store that listens for actions and updates its state accordingly, informing any
|
||||
* listeners (views) of state changes.
|
||||
*/
|
||||
class LifecycleStore extends Store<ActionPayload> {
|
||||
private state: IState = INITIAL_STATE;
|
||||
|
||||
class LifecycleStore extends AsyncStore<IState> {
|
||||
public constructor() {
|
||||
super(dis);
|
||||
super(dis, INITIAL_STATE);
|
||||
}
|
||||
|
||||
private setState(newState: Partial<IState>): void {
|
||||
this.state = Object.assign(this.state, newState);
|
||||
this.__emitChange();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
protected __onDispatch(payload: ActionPayload | DoAfterSyncPreparedPayload<ActionPayload>): void {
|
||||
protected onDispatch(payload: ActionPayload | DoAfterSyncPreparedPayload<ActionPayload>): void {
|
||||
switch (payload.action) {
|
||||
case Action.DoAfterSyncPrepared:
|
||||
this.setState({
|
||||
this.updateState({
|
||||
deferredAction: payload.deferred_action,
|
||||
});
|
||||
break;
|
||||
case "cancel_after_sync_prepared":
|
||||
this.setState({
|
||||
this.updateState({
|
||||
deferredAction: null,
|
||||
});
|
||||
break;
|
||||
|
@ -65,7 +56,7 @@ class LifecycleStore extends Store<ActionPayload> {
|
|||
}
|
||||
if (!this.state.deferredAction) break;
|
||||
const deferredAction = Object.assign({}, this.state.deferredAction);
|
||||
this.setState({
|
||||
this.updateState({
|
||||
deferredAction: null,
|
||||
});
|
||||
dis.dispatch(deferredAction);
|
||||
|
@ -77,10 +68,6 @@ class LifecycleStore extends Store<ActionPayload> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private reset(): void {
|
||||
this.state = Object.assign({}, INITIAL_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
let singletonLifecycleStore: LifecycleStore | null = null;
|
||||
|
|
|
@ -16,19 +16,19 @@
|
|||
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { SyncState } from "matrix-js-sdk/src/sync";
|
||||
import { Dispatcher } from "flux";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
import { ActionPayload } from "../dispatcher/payloads";
|
||||
import { IDestroyable } from "../utils/IDestroyable";
|
||||
import { Action } from "../dispatcher/actions";
|
||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
|
||||
export abstract class ReadyWatchingStore extends EventEmitter implements IDestroyable {
|
||||
protected matrixClient: MatrixClient | null = null;
|
||||
private dispatcherRef: string | null = null;
|
||||
|
||||
public constructor(protected readonly dispatcher: Dispatcher<ActionPayload>) {
|
||||
public constructor(protected readonly dispatcher: MatrixDispatcher) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
|
88
test/dispatcher/dispatcher-test.ts
Normal file
88
test/dispatcher/dispatcher-test.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import defaultDispatcher from "../../src/dispatcher/dispatcher";
|
||||
import { Action } from "../../src/dispatcher/actions";
|
||||
import { AsyncActionPayload } from "../../src/dispatcher/payloads";
|
||||
|
||||
describe("MatrixDispatcher", () => {
|
||||
it("should throw error if unregistering unknown token", () => {
|
||||
expect(() => defaultDispatcher.unregister("not-a-real-token")).toThrow(
|
||||
"Dispatcher.unregister(...): 'not-a-real-token' does not map to a registered callback.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should execute callbacks in registered order", async () => {
|
||||
const deferred1 = defer<number>();
|
||||
const deferred2 = defer<number>();
|
||||
|
||||
const fn1 = jest.fn(() => deferred1.resolve(1));
|
||||
const fn2 = jest.fn(() => deferred2.resolve(2));
|
||||
|
||||
defaultDispatcher.register(fn1);
|
||||
defaultDispatcher.register(fn2);
|
||||
|
||||
defaultDispatcher.dispatch({ action: Action.OnLoggedIn });
|
||||
const res = await Promise.race([deferred1.promise, deferred2.promise]);
|
||||
|
||||
expect(res).toBe(1);
|
||||
});
|
||||
|
||||
it("should skip the queue for the given callback", async () => {
|
||||
const deferred1 = defer<number>();
|
||||
const deferred2 = defer<number>();
|
||||
|
||||
const fn1 = jest.fn(() => deferred1.resolve(1));
|
||||
const fn2 = jest.fn(() => deferred2.resolve(2));
|
||||
|
||||
defaultDispatcher.register(() => {
|
||||
defaultDispatcher.waitFor([id2]);
|
||||
});
|
||||
defaultDispatcher.register(fn1);
|
||||
const id2 = defaultDispatcher.register(fn2);
|
||||
|
||||
defaultDispatcher.dispatch({ action: Action.OnLoggedIn });
|
||||
const res = await Promise.race([deferred1.promise, deferred2.promise]);
|
||||
|
||||
expect(res).toBe(2);
|
||||
});
|
||||
|
||||
it("should not fire callback which was added during a dispatch", () => {
|
||||
const fn2 = jest.fn();
|
||||
|
||||
defaultDispatcher.register(() => {
|
||||
defaultDispatcher.register(fn2);
|
||||
});
|
||||
|
||||
defaultDispatcher.dispatch({ action: Action.OnLoggedIn }, true);
|
||||
|
||||
expect(fn2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should handle AsyncActionPayload", () => {
|
||||
const fn = jest.fn();
|
||||
defaultDispatcher.register(fn);
|
||||
|
||||
const readyFn = jest.fn((dispatch) => {
|
||||
dispatch({ action: "test" });
|
||||
});
|
||||
defaultDispatcher.dispatch(new AsyncActionPayload(readyFn), true);
|
||||
|
||||
expect(fn).toHaveBeenLastCalledWith(expect.objectContaining({ action: "test" }));
|
||||
});
|
||||
});
|
67
yarn.lock
67
yarn.lock
|
@ -2150,24 +2150,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
|
||||
|
||||
"@types/fbemitter@*":
|
||||
version "2.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/fbemitter/-/fbemitter-2.0.32.tgz#8ed204da0f54e9c8eaec31b1eec91e25132d082c"
|
||||
integrity sha512-Hwq28bBlbmfCgLnNJvjl5ssTrbZCTSblI4vqPpqZrbbEL8vn5l2UivxhlMYfUY7a4SR8UB6RKoLjOZfljqAa6g==
|
||||
|
||||
"@types/file-saver@^2.0.3":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.5.tgz#9ee342a5d1314bb0928375424a2f162f97c310c7"
|
||||
integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
|
||||
|
||||
"@types/flux@^3.1.9":
|
||||
version "3.1.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/flux/-/flux-3.1.11.tgz#e030d61e6c7fd6187dfa0e7e3dfcc8036c511581"
|
||||
integrity sha512-Aq4UB1ZqAKcPbhB0GpgMw2sntvOh71he9tjz53TLKrI7rw3Y3LxCW5pTYY9IV455hQapm4pmxFjpqlWOs308Yg==
|
||||
dependencies:
|
||||
"@types/fbemitter" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/fs-extra@^11.0.0":
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.1.tgz#f542ec47810532a8a252127e6e105f487e0a6ea5"
|
||||
|
@ -3506,13 +3493,6 @@ crc-32@^0.3.0:
|
|||
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-0.3.0.tgz#6a3d3687f5baec41f7e9b99fe1953a2e5d19775e"
|
||||
integrity sha512-kucVIjOmMc1f0tv53BJ/5WIX+MGLcKuoBhnGqQrgKJNqLByb/sVMWfW/Aw6hw0jgcqjJ2pi9E5y32zOIpaUlsA==
|
||||
|
||||
cross-fetch@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
|
||||
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
|
||||
dependencies:
|
||||
node-fetch "2.6.7"
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
|
@ -4573,31 +4553,6 @@ fb-watchman@^2.0.0:
|
|||
dependencies:
|
||||
bser "2.1.1"
|
||||
|
||||
fbemitter@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3"
|
||||
integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==
|
||||
dependencies:
|
||||
fbjs "^3.0.0"
|
||||
|
||||
fbjs-css-vars@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
|
||||
integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
|
||||
|
||||
fbjs@^3.0.0, fbjs@^3.0.1:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6"
|
||||
integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==
|
||||
dependencies:
|
||||
cross-fetch "^3.1.5"
|
||||
fbjs-css-vars "^1.0.0"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.30"
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
|
@ -4709,14 +4664,6 @@ flatted@^3.1.0:
|
|||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
|
||||
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
|
||||
|
||||
flux@4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.3.tgz#573b504a24982c4768fdfb59d8d2ea5637d72ee7"
|
||||
integrity sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==
|
||||
dependencies:
|
||||
fbemitter "^3.0.0"
|
||||
fbjs "^3.0.1"
|
||||
|
||||
focus-lock@^0.11.6:
|
||||
version "0.11.6"
|
||||
resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.6.tgz#e8821e21d218f03e100f7dc27b733f9c4f61e683"
|
||||
|
@ -6799,7 +6746,7 @@ nwsapi@^2.2.2:
|
|||
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
|
||||
integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
|
||||
|
@ -7266,13 +7213,6 @@ process-nextick-args@~2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prompts@^2.0.1:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
|
||||
|
@ -8494,11 +8434,6 @@ typescript@4.9.5:
|
|||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||
|
||||
ua-parser-js@^0.7.30:
|
||||
version "0.7.32"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.32.tgz#cd8c639cdca949e30fa68c44b7813ef13e36d211"
|
||||
integrity sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==
|
||||
|
||||
ua-parser-js@^1.0.2:
|
||||
version "1.0.33"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.33.tgz#f21f01233e90e7ed0f059ceab46eb190ff17f8f4"
|
||||
|
|
Loading…
Reference in a new issue