1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-24 11:01:41 +01:00

Initialize composable observable store after update (#20468)

* Initialize composable observable store after update

The composable observable store now updates state immediately when the
structure is updated. Previously each store would only be updated after
the first state change. This ensures that the composable observable
store state is always complete.

* SUpport falsy controller state

We now use the nullish coalescing operator when checkint store.state, so that we don't accidentally ignore falsy state.

Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>

* Add test for falsy controller state

* Update state snapshots

A change on `develop` required another state update.

---------

Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
This commit is contained in:
Mark Stacey 2023-08-17 12:22:37 -02:30 committed by GitHub
parent 2529b360be
commit 4cf886f710
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 0 deletions

View File

@ -51,6 +51,7 @@ export default class ComposableObservableStore extends ObservableStore {
updateStructure(config) {
this.config = config;
this.removeAllListeners();
const initialState = {};
for (const key of Object.keys(config)) {
if (!config[key]) {
throw new Error(`Undefined '${key}'`);
@ -72,7 +73,10 @@ export default class ComposableObservableStore extends ObservableStore {
},
);
}
initialState[key] = store.state ?? store.getState?.();
}
this.updateState(initialState);
}
/**

View File

@ -120,6 +120,46 @@ describe('ComposableObservableStore', () => {
});
});
it('should initialize state with all three types of stores', () => {
const controllerMessenger = new ControllerMessenger();
const exampleStore = new ObservableStore();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const oldExampleController = new OldExampleController();
exampleStore.putState('state');
exampleController.updateBar('state');
oldExampleController.updateBaz('state');
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({
Example: exampleController,
OldExample: oldExampleController,
Store: exampleStore,
});
expect(store.getState()).toStrictEqual({
Example: { bar: 'state' },
OldExample: { baz: 'state' },
Store: 'state',
});
});
it('should initialize falsy state', () => {
const controllerMessenger = new ControllerMessenger();
const exampleStore = new ObservableStore();
exampleStore.putState(false);
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({
Example: exampleStore,
});
expect(store.getState()).toStrictEqual({
Example: false,
});
});
it('should return flattened state', () => {
const controllerMessenger = new ControllerMessenger();
const fooStore = new ObservableStore({ foo: 'foo' });

View File

@ -1,5 +1,18 @@
{
"AccountTracker": { "accounts": "object" },
"AddressBookController": "object",
"AlertController": {
"alertEnabledness": { "unconnectedAccount": true, "web3ShimUsage": true },
"unconnectedAccountAlertShownOrigins": "object",
"web3ShimUsageOrigins": "object"
},
"AnnouncementController": "object",
"AppMetadataController": {
"currentAppVersion": "10.34.4",
"previousAppVersion": "",
"previousMigrationVersion": 0,
"currentMigrationVersion": 94
},
"AppStateController": {
"connectedStatusPopoverHasBeenShown": true,
"defaultHomeActiveTabName": null,
@ -24,6 +37,7 @@
},
"ApprovalController": "object",
"CachedBalancesController": "object",
"CronjobController": "object",
"CurrencyController": {
"conversionDate": "number",
"conversionRate": 1700,
@ -42,6 +56,22 @@
"unapprovedEncryptionPublicKeyMsgCount": 0
},
"EnsController": "object",
"GasFeeController": "object",
"IncomingTransactionsController": {
"incomingTransactions": "object",
"incomingTxLastFetchedBlockByChainId": {
"0x1": null,
"0xe708": null,
"0x5": null,
"0xaa36a7": null,
"0xe704": null
}
},
"KeyringController": {
"isUnlocked": false,
"keyringTypes": "object",
"keyrings": "object"
},
"MetaMetricsController": {
"participateInMetaMetrics": true,
"metaMetricsId": "fake-metrics-id",
@ -66,6 +96,51 @@
"networksMetadata": "object",
"networkConfigurations": "object"
},
"NftController": "object",
"NotificationController": "object",
"OnboardingController": {
"seedPhraseBackedUp": true,
"firstTimeFlowType": "import",
"completedOnboarding": true,
"onboardingTabs": "object"
},
"PermissionController": "object",
"PermissionLogController": "object",
"PreferencesController": {
"useBlockie": false,
"useNonceField": false,
"usePhishDetect": true,
"dismissSeedBackUpReminder": "boolean",
"disabledRpcMethodPreferences": "object",
"useMultiAccountBalanceChecker": "boolean",
"useTokenDetection": "boolean",
"useNftDetection": "boolean",
"use4ByteResolution": "boolean",
"useCurrencyRateCheck": "boolean",
"openSeaEnabled": "boolean",
"advancedGasFee": "object",
"featureFlags": { "showIncomingTransactions": true },
"knownMethodData": "object",
"currentLocale": "en",
"identities": "object",
"lostIdentities": "object",
"forgottenPassword": false,
"preferences": {
"hideZeroBalanceTokens": false,
"showFiatInTestnets": false,
"showTestNetworks": false,
"useNativeCurrencyAsPrimaryCurrency": true
},
"ipfsGateway": "dweb.link",
"useAddressBarEnsResolution": "boolean",
"infuraBlocked": "boolean",
"ledgerTransportType": "string",
"snapRegistryList": "object",
"transactionSecurityCheckEnabled": "boolean",
"theme": "string",
"isLineaMainnetReleased": "boolean",
"selectedAddress": "string"
},
"SignatureController": {
"unapprovedMsgs": "object",
"unapprovedPersonalMsgs": "object",
@ -74,7 +149,12 @@
"unapprovedPersonalMsgCount": 0,
"unapprovedTypedMessagesCount": 0
},
"SmartTransactionsController": "object",
"SnapController": "object",
"SnapsRegistry": "object",
"SubjectMetadataController": "object",
"SwapsController": "object",
"TokenListController": "object",
"TokenRatesController": "object",
"TokensController": "object",
"TxController": "object"