From 5ea2003f6028cff17a4dccb29cc305f6025bca1b Mon Sep 17 00:00:00 2001 From: Suren Atoyan Date: Wed, 26 Jun 2019 11:08:56 +0400 Subject: [PATCH] update diff editor content --- demo/package.json | 2 +- demo/src/config/diff.js | 1554 ++++----------------------------- demo/src/store/state/index.js | 2 +- demo/yarn.lock | 224 ++--- 4 files changed, 298 insertions(+), 1484 deletions(-) diff --git a/demo/package.json b/demo/package.json index b8b0921..e73f3a4 100644 --- a/demo/package.json +++ b/demo/package.json @@ -7,7 +7,7 @@ "@material-ui/icons": "^4.2.0", "@material-ui/lab": "^4.0.0-alpha.16", "@material-ui/styles": "^4.1.1", - "@monaco-editor/react": "^1.0.0", + "@monaco-editor/react": "^1.0.1", "classnames": "^2.2.6", "mobile-detect": "^1.4.3", "overmind": "^18.0.1", diff --git a/demo/src/config/diff.js b/demo/src/config/diff.js index 4589a30..d1d0e94 100644 --- a/demo/src/config/diff.js +++ b/demo/src/config/diff.js @@ -1,1420 +1,224 @@ +/* eslint-disable */ import { rTabs } from 'utils'; const examples = { original: rTabs(` - // Copyright (c) The Libra Core Contributors - // SPDX-License-Identifier: Apache-2.0 + # monaco-react + Monaco Editor for React - //! This crate provides [\`LibraDB\`] which represents physical storage of the core Libra data - //! structures. - //! - //! It relays read/write operations on the physical storage via [\`schemadb\`] to the underlying - //! Key-Value storage system, and implements libra data structures on top of it. + [![NPM](https://nodei.co/npm/@monaco-editor/react.png.png)](https://nodei.co/npm/@monaco-editor/react/) - // Used in other crates for testing. - pub mod mock_genesis; - // Used in this and other crates for testing. - pub mod test_helper; + ## Motivation + There is a well-known web technology based code editor called [Monaco Editor](https://microsoft.github.io/monaco-editor/) that powers [VS Code](https://code.visualstudio.com/). [There are also many ways to integrate](https://github.com/Microsoft/monaco-editor-samples/) it provided by monaco creators. But there were tons of problems with integration of monaco with modern technologies; e.g React. - pub mod errors; + There also exist solutions for integration with React; e.g [this one](https://github.com/react-monaco-editor/react-monaco-editor) and [this one](https://github.com/jaywcjlove/react-monacoeditor). But they need some custom webpack configuration to make Monaco fully work, which is not the "best" solution for such kind of things like create-react-app - [CRA](https://facebook.github.io/create-react-app/). - mod event_store; - mod ledger_store; - pub mod schema; - mod state_store; - mod transaction_store; + With this solution, you don't need any kind of webpack configuration files and it works great with React apps created by CRA or created by something else. - #[cfg(test)] - mod libradb_test; + ## Installation - use crate::{ - event_store::EventStore, ledger_store::LedgerStore, schema::*, state_store::StateStore, - transaction_store::TransactionStore, - }; - use crypto::{ - hash::{CryptoHash, SPARSE_MERKLE_PLACEHOLDER_HASH}, - HashValue, - }; - use failure::prelude::*; - use itertools::{izip, zip_eq}; - use lazy_static::lazy_static; - use logger::prelude::*; - use metrics::OpMetrics; - use schemadb::{ColumnFamilyOptions, ColumnFamilyOptionsMap, SchemaBatch, DB, DEFAULT_CF_NAME}; - use std::{iter::Iterator, path::Path, sync::Arc, time::Instant}; - use storage_proto::ExecutorStartupInfo; - use types::{ - access_path::AccessPath, - account_address::AccountAddress, - account_config::get_account_resource_or_default, - account_state_blob::{AccountStateBlob, AccountStateWithProof}, - contract_event::EventWithProof, - get_with_proof::{RequestItem, ResponseItem}, - ledger_info::LedgerInfoWithSignatures, - proof::{AccountStateProof, EventProof, SignedTransactionProof, SparseMerkleProof}, - transaction::{ - SignedTransactionWithProof, TransactionInfo, TransactionListWithProof, TransactionToCommit, - Version, - }, - validator_change::ValidatorChangeEventWithProof, - }; + \`\`\`bash + yarn add @monaco-editor/react # or npm install @monaco-editor/react + \`\`\` - lazy_static! { - static ref OP_COUNTER: OpMetrics = OpMetrics::new_and_registered("storage"); + ## [Demo](https://monaco-react.surenatoyan.com/) + + ## Usage + + Example + \`\`\`js + import React, { useState } from 'react'; + import Editor from '@monaco-editor/react'; + + const examples = { python: '# python example', javascript: '// javascript example' }; + + function App() { + const [theme, setTheme] = useState('light'); + const [language, setLanguage] = useState('javascript'); + const [isEditorReady, setIsEditorReady] = useState(false); + + function handleEditorDidMount() { + setIsEditorReady(true); + } + + function toggleTheme() { + setTheme(theme === 'light' ? 'dark' : 'light'); + } + + function toggleLanguage() { + setLanguage(language === 'javascript' ? 'python' : 'javascript'); + } + + return ( + <> + + + + + + ); } - /// This holds a handle to the underlying DB responsible for physical storage and provides APIs for - /// access to the core Libra data structures. - pub struct LibraDB { - db: Arc, - ledger_store: LedgerStore, - transaction_store: TransactionStore, - state_store: StateStore, - event_store: EventStore, - } + export default App; + \`\`\` - impl LibraDB { - /// This creates an empty LibraDB instance on disk or opens one if it already exists. - pub fn new + Clone>(db_root_path: P) -> Self { - let cf_opts_map: ColumnFamilyOptionsMap = [ - ( - /* LedgerInfo CF = */ DEFAULT_CF_NAME, - ColumnFamilyOptions::default(), - ), - (ACCOUNT_STATE_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_ACCUMULATOR_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_BY_ACCESS_PATH_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_CF_NAME, ColumnFamilyOptions::default()), - (SIGNATURE_CF_NAME, ColumnFamilyOptions::default()), - (SIGNED_TRANSACTION_CF_NAME, ColumnFamilyOptions::default()), - (STATE_MERKLE_NODE_CF_NAME, ColumnFamilyOptions::default()), - ( - TRANSACTION_ACCUMULATOR_CF_NAME, - ColumnFamilyOptions::default(), - ), - (TRANSACTION_INFO_CF_NAME, ColumnFamilyOptions::default()), - (VALIDATOR_CF_NAME, ColumnFamilyOptions::default()), - ] - .iter() - .cloned() - .collect(); + #### MonacoEditor instance - let path = db_root_path.as_ref().join("libradb"); - let instant = Instant::now(); - let db = Arc::new( - DB::open(path.clone(), cf_opts_map) - .unwrap_or_else(|e| panic!("LibraDB open failed: {:?}", e)), - ); + The second argument of \`editorDidMount\` is the instance of the editor. So, you can use it to get the full control on the editor if you need it. - info!( - "Opened LibraDB at {:?} in {} ms", - path, - instant.elapsed().as_millis() - ); + ## Props - LibraDB { - db: Arc::clone(&db), - event_store: EventStore::new(Arc::clone(&db)), - ledger_store: LedgerStore::new(Arc::clone(&db)), - state_store: StateStore::new(Arc::clone(&db)), - transaction_store: TransactionStore::new(Arc::clone(&db)), - } - } + #### Editor - // ================================== Public API ================================== - /// Returns the account state corresponding to the given version and account address with proof - /// based on \`ledger_version\` - fn get_account_state_with_proof( - &self, - address: AccountAddress, - version: Version, - ledger_version: Version, - ) -> Result { - ensure!( - version <= ledger_version, - "The queried version {} should be equal to or older than ledger version {}.", - version, - ledger_version - ); - let latest_version = self.get_latest_version()?; - ensure!( - ledger_version <= latest_version, - "The ledger version {} is greather than the latest version currently in ledger: {}", - ledger_version, - latest_version - ); + | Name | Type | Default | Description | + |:----------|:-------------|:------|:------| + | value | string || The editor value | + | language | enum: ... | | All languages that are [supported](https://github.com/microsoft/monaco-languages) by monaco-editor | + | editorDidMount | func | noop | **Signature: function(getEditorValue: func, monaco: object) => void**
This function will be called right after monaco editor will be mounted and ready to work. It will get the editor instance as a second argument | + | theme | enum: 'light' \| 'dark' | 'light' | Default themes of monaco | + | line | number | | The line to jump on it | + | width | union: number \| string | '100%' | The width of the editor wrapper | + | height | union: number \| string | '100%' | The height of the editor wrapper | + | options | object | {} | [IEditorOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditoroptions.html) | - let (txn_info, txn_info_accumulator_proof) = self - .ledger_store - .get_transaction_info_with_proof(version, ledger_version)?; - let (account_state_blob, sparse_merkle_proof) = self - .state_store - .get_account_state_with_proof_by_state_root(address, txn_info.state_root_hash())?; - Ok(AccountStateWithProof::new( - version, - account_state_blob, - AccountStateProof::new(txn_info_accumulator_proof, txn_info, sparse_merkle_proof), - )) - } + #### DiffEditor - /// Returns events specified by \`access_path\` with sequence number in range designated by - /// \`start_seq_num\`, \`ascending\` and \`limit\`. If ascending is true this query will return up to - /// \`limit\` events that were emitted after \`start_event_seq_num\`. Otherwise it will return up to - /// \`limit\` events in the reverse order. Both cases are inclusive. - fn get_events_by_event_access_path( - &self, - access_path: &AccessPath, - start_seq_num: u64, - ascending: bool, - limit: u64, - ledger_version: Version, - ) -> Result<(Vec, Option)> { - let get_latest = !ascending && start_seq_num == u64::max_value(); - let cursor = if get_latest { - // Caller wants the latest, figure out the latest seq_num. - // In the case of no events on that path, use 0 and expect empty result below. - self.event_store - .get_latest_sequence_number(ledger_version, access_path)? - .unwrap_or(0) - } else { - start_seq_num - }; + | Name | Type | Default | Description | + |:----------|:-------------|:------|:------| + | original | string || The original source (left one) value | + | modified | string || The modified source (right one) value | + | language | enum: ... | | All languages that are [supported](https://github.com/microsoft/monaco-languages) by monaco-editor | + | originalLanguage | enum: ... | *language | This prop gives you the opportunity to specify the language of the \`original\` source separately, otherwise, it will get the value of \`language\` property. (Possible values are the same as \`language\`) | + | modifiedLanguage | enum: ... | *language | This prop gives you the opportunity to specify the language of the \`modified\` source separately, otherwise, it will get the value of \`language\` property. (Possible values are the same as \`language\`) | + | editorDidMount | func | noop | **Signature: function(getOriginalEditorValue: func, getModifiedEditorValue: func, monaco: object) => void**
This function will be called right after monaco editor will be mounted and ready to work. It will get the editor instance as a third argument | + | theme | enum: 'light' \| 'dark' | 'light' | Default themes of monaco | + | line | number | | The line to jump on it | + | width | union: number \| string | '100%' | The width of the editor wrapper | + | height | union: number \| string | '100%' | The height of the editor wrapper | + | options | object | {} | [IDiffEditorOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.idiffeditorconstructionoptions.html) | - // Convert requested range and order to a range in ascending order. - let (first_seq, real_limit) = get_first_seq_num_and_limit(ascending, cursor, limit)?; + ## License - // Query the index. - let mut event_keys = self.event_store.lookup_events_by_access_path( - access_path, - first_seq, - real_limit, - ledger_version, - )?; - - // When descending, it's possible that user is asking for something beyond the latest - // sequence number, in which case we will consider it a bad request and return an empty - // list. - // For example, if the latest sequence number is 100, and the caller is asking for 110 to - // 90, we will get 90 to 100 from the index lookup above. Seeing that the last item - // is 100 instead of 110 tells us 110 is out of bound. - if !ascending { - if let Some((seq_num, _, _)) = event_keys.last() { - if *seq_num < cursor { - event_keys = Vec::new(); - } - } - } - - let mut events_with_proof = event_keys - .into_iter() - .map(|(seq, ver, idx)| { - let (event, event_proof) = self - .event_store - .get_event_with_proof_by_version_and_index(ver, idx)?; - ensure!( - seq == event.sequence_number(), - "Index broken, expected seq:{}, actual:{}", - seq, - event.sequence_number() - ); - let (txn_info, txn_info_proof) = self - .ledger_store - .get_transaction_info_with_proof(ver, ledger_version)?; - let proof = EventProof::new(txn_info_proof, txn_info, event_proof); - Ok(EventWithProof::new(ver, idx, event, proof)) - }) - .collect::>>()?; - if !ascending { - events_with_proof.reverse(); - } - - // There are two cases where we need to return proof_of_latest_event to let the caller know - // the latest sequence number: - // 1. The user asks for the latest event by using u64::max() as the cursor, apparently - // he doesn't know the latest sequence number. - // 2. We are going to return less than \`real_limit\` items. (Two cases can lead to that: - // a. the cursor is beyond the latest sequence number; b. in ascending order we don't have - // enough items to return because the latest sequence number is hit). In this case we - // need to return the proof to convince the caller we didn't hide any item from him. Note - // that we use \`real_limit\` instead of \`limit\` here because it takes into account the case - // of hitting 0 in descending order, which is valid and doesn't require the proof. - let proof_of_latest_event = if get_latest || events_with_proof.len() < real_limit as usize { - Some(self.get_account_state_with_proof( - access_path.address, - ledger_version, - ledger_version, - )?) - } else { - None - }; - - Ok((events_with_proof, proof_of_latest_event)) - } - - /// Returns a signed transaction that is the \`seq_num\`-th one associated with the given account. - /// If the signed transaction with given \`seq_num\` doesn't exist, returns \`None\`. - // TODO(gzh): Use binary search for now. We may create seq_num index in the future. - fn get_txn_by_account_and_seq( - &self, - address: AccountAddress, - seq_num: u64, - ledger_version: Version, - fetch_events: bool, - ) -> Result> { - // If txn with seq_num n is at some version, the corresponding account state at the - // same version will be the first account state that has seq_num n + 1. - let seq_num = seq_num + 1; - let (mut start_version, mut end_version) = (0, ledger_version); - while start_version < end_version { - let mid_version = start_version + (end_version - start_version) / 2; - let account_seq_num = self.get_account_seq_num_by_version(address, mid_version)?; - if account_seq_num >= seq_num { - end_version = mid_version; - } else { - start_version = mid_version + 1; - } - } - assert_eq!(start_version, end_version); - - let seq_num_found = self.get_account_seq_num_by_version(address, start_version)?; - if seq_num_found < seq_num { - return Ok(None); - } else if seq_num_found > seq_num { - // log error - bail!("internal error: seq_num is not continuous.") - } - // start_version cannot be 0 (genesis version). - assert_eq!( - self.get_account_seq_num_by_version(address, start_version - 1)?, - seq_num_found - 1 - ); - self.get_transaction_with_proof(start_version, ledger_version, fetch_events) - .map(Some) - } - - /// Gets the latest version number available in the ledger. - fn get_latest_version(&self) -> Result { - Ok(self - .ledger_store - .get_latest_ledger_info()? - .ledger_info() - .version()) - } - - /// Persist transactions. Called by the executor module when either syncing nodes or committing - /// blocks during normal operation. - /// - /// When \`ledger_info_with_sigs\` is provided, verify that the transaction accumulator root hash - /// it carries is generated after the \`txns_to_commit\` are applied. - pub fn save_transactions( - &self, - txns_to_commit: &[TransactionToCommit], - first_version: Version, - ledger_info_with_sigs: &Option, - ) -> Result<()> { - let num_txns = txns_to_commit.len() as u64; - // ledger_info_with_sigs could be None if we are doing state synchronization. In this case - // txns_to_commit should not be empty. Otherwise it is okay to commit empty blocks. - ensure!( - ledger_info_with_sigs.is_some() || num_txns > 0, - "txns_to_commit is empty while ledger_info_with_sigs is None.", - ); - - let cur_state_root_hash = if first_version == 0 { - *SPARSE_MERKLE_PLACEHOLDER_HASH - } else { - self.ledger_store - .get_transaction_info(first_version - 1)? - .state_root_hash() - }; - - if let Some(x) = ledger_info_with_sigs { - let last_version = x.ledger_info().version(); - ensure!( - first_version + num_txns - 1 == last_version, - "Transaction batch not applicable: first_version {}, num_txns {}, last_version {}", - first_version, - num_txns, - last_version - ); - } - - // Gather db mutations to \`batch\`. - let mut batch = SchemaBatch::new(); - - let new_root_hash = self.save_transactions_impl( - txns_to_commit, - first_version, - cur_state_root_hash, - &mut batch, - )?; - - // If expected ledger info is provided, verify result root hash and save the ledger info. - if let Some(x) = ledger_info_with_sigs { - let expected_root_hash = x.ledger_info().transaction_accumulator_hash(); - ensure!( - new_root_hash == expected_root_hash, - "Root hash calculated doesn't match expected. {:?} vs {:?}", - new_root_hash, - expected_root_hash, - ); - - self.ledger_store.put_ledger_info(x, &mut batch)?; - } - - // Persist. - self.commit(batch)?; - // Only increment counter if commit(batch) succeeds. - OP_COUNTER.inc_by("committed_txns", txns_to_commit.len()); - Ok(()) - } - - fn save_transactions_impl( - &self, - txns_to_commit: &[TransactionToCommit], - first_version: u64, - cur_state_root_hash: HashValue, - mut batch: &mut SchemaBatch, - ) -> Result { - let last_version = first_version + txns_to_commit.len() as u64 - 1; - - // Account state updates. Gather account state root hashes - let account_state_sets = txns_to_commit - .iter() - .map(|txn_to_commit| txn_to_commit.account_states().clone()) - .collect::>(); - let state_root_hashes = self.state_store.put_account_state_sets( - account_state_sets, - cur_state_root_hash, - &mut batch, - )?; - - // Event updates. Gather event accumulator root hashes. - let event_root_hashes = zip_eq(first_version..=last_version, txns_to_commit) - .map(|(ver, txn_to_commit)| { - self.event_store - .put_events(ver, txn_to_commit.events(), &mut batch) - }) - .collect::>>()?; - - // Transaction updates. Gather transaction hashes. - zip_eq(first_version..=last_version, txns_to_commit) - .map(|(ver, txn_to_commit)| { - self.transaction_store - .put_transaction(ver, txn_to_commit.signed_txn(), &mut batch) - }) - .collect::>()?; - let txn_hashes = txns_to_commit - .iter() - .map(|txn_to_commit| txn_to_commit.signed_txn().hash()) - .collect::>(); - let gas_amounts = txns_to_commit - .iter() - .map(TransactionToCommit::gas_used) - .collect::>(); - - // Transaction accumulator updates. Get result root hash. - let txn_infos = izip!( - txn_hashes, - state_root_hashes, - event_root_hashes, - gas_amounts - ) - .map(|(t, s, e, g)| TransactionInfo::new(t, s, e, g)) - .collect::>(); - assert_eq!(txn_infos.len(), txns_to_commit.len()); - - let new_root_hash = - self.ledger_store - .put_transaction_infos(first_version, &txn_infos, &mut batch)?; - - Ok(new_root_hash) - } - - /// This backs the \`UpdateToLatestLedger\` public read API which returns the latest - /// [\`LedgerInfoWithSignatures\`] together with items requested and proofs relative to the same - /// ledger info. - pub fn update_to_latest_ledger( - &self, - _client_known_version: u64, - request_items: Vec, - ) -> Result<( - Vec, - LedgerInfoWithSignatures, - Vec, - )> { - // Get the latest ledger info and signatures - let ledger_info_with_sigs = self.ledger_store.get_latest_ledger_info()?; - let ledger_version = ledger_info_with_sigs.ledger_info().version(); - - // Fulfill all request items - let response_items = request_items - .into_iter() - .map(|request_item| match request_item { - RequestItem::GetAccountState { address } => Ok(ResponseItem::GetAccountState { - account_state_with_proof: self.get_account_state_with_proof( - address, - ledger_version, - ledger_version, - )?, - }), - RequestItem::GetAccountTransactionBySequenceNumber { - account, - sequence_number, - fetch_events, - } => { - let signed_transaction_with_proof = self.get_txn_by_account_and_seq( - account, - sequence_number, - ledger_version, - fetch_events, - )?; - - let proof_of_current_sequence_number = match signed_transaction_with_proof { - Some(_) => None, - None => Some(self.get_account_state_with_proof( - account, - ledger_version, - ledger_version, - )?), - }; - - Ok(ResponseItem::GetAccountTransactionBySequenceNumber { - signed_transaction_with_proof, - proof_of_current_sequence_number, - }) - } - - RequestItem::GetEventsByEventAccessPath { - access_path, - start_event_seq_num, - ascending, - limit, - } => { - let (events_with_proof, proof_of_latest_event) = self - .get_events_by_event_access_path( - &access_path, - start_event_seq_num, - ascending, - limit, - ledger_version, - )?; - Ok(ResponseItem::GetEventsByEventAccessPath { - events_with_proof, - proof_of_latest_event, - }) - } - RequestItem::GetTransactions { - start_version, - limit, - fetch_events, - } => { - let txn_list_with_proof = - self.get_transactions(start_version, limit, ledger_version, fetch_events)?; - - Ok(ResponseItem::GetTransactions { - txn_list_with_proof, - }) - } - }) - .collect::>>()?; - - Ok(( - response_items, - ledger_info_with_sigs, - vec![], /* TODO: validator_change_events */ - )) - } - - // =========================== Execution Internal APIs ======================================== - - /// Gets an account state by account address, out of the ledger state indicated by the state - /// Merkle tree root hash. - /// - /// This is used by the executor module internally. - pub fn get_account_state_with_proof_by_state_root( - &self, - address: AccountAddress, - state_root: HashValue, - ) -> Result<(Option, SparseMerkleProof)> { - self.state_store - .get_account_state_with_proof_by_state_root(address, state_root) - } - - /// Gets information needed from storage during the startup of the executor module. - /// - /// This is used by the executor module internally. - pub fn get_executor_startup_info(&self) -> Result> { - // Get the latest ledger info. Return None if not bootstrapped. - let ledger_info_with_sigs = match self.ledger_store.get_latest_ledger_info_option()? { - Some(x) => x, - None => return Ok(None), - }; - let ledger_info = ledger_info_with_sigs.ledger_info().clone(); - - let (latest_version, txn_info) = self.ledger_store.get_latest_transaction_info()?; - - let account_state_root_hash = txn_info.state_root_hash(); - - let ledger_frozen_subtree_hashes = self - .ledger_store - .get_ledger_frozen_subtree_hashes(latest_version)?; - - Ok(Some(ExecutorStartupInfo { - ledger_info, - latest_version, - account_state_root_hash, - ledger_frozen_subtree_hashes, - })) - } - - // ======================= State Synchronizer Internal APIs =================================== - /// Gets a batch of transactions for the purpose of synchronizing state to another node. - /// - /// This is used by the State Synchronizer module internally. - pub fn get_transactions( - &self, - start_version: Version, - limit: u64, - ledger_version: Version, - fetch_events: bool, - ) -> Result { - if start_version > ledger_version || limit == 0 { - return Ok(TransactionListWithProof::new_empty()); - } - - let limit = std::cmp::min(limit, ledger_version - start_version + 1); - let txn_and_txn_info_list = (start_version..start_version + limit) - .into_iter() - .map(|version| { - Ok(( - self.transaction_store.get_transaction(version)?, - self.ledger_store.get_transaction_info(version)?, - )) - }) - .collect::>>()?; - let proof_of_first_transaction = Some( - self.ledger_store - .get_transaction_proof(start_version, ledger_version)?, - ); - let proof_of_last_transaction = if limit == 1 { - None - } else { - Some( - self.ledger_store - .get_transaction_proof(start_version + limit - 1, ledger_version)?, - ) - }; - let events = if fetch_events { - Some( - (start_version..start_version + limit) - .into_iter() - .map(|version| Ok(self.event_store.get_events_by_version(version)?)) - .collect::>>()?, - ) - } else { - None - }; - - Ok(TransactionListWithProof::new( - txn_and_txn_info_list, - events, - Some(start_version), - proof_of_first_transaction, - proof_of_last_transaction, - )) - } - - // ================================== Private APIs ================================== - /// Write the whole schema batch including all data necessary to mutate the ledge - /// state of some transaction by leveraging rocksdb atomicity support. - fn commit(&self, batch: SchemaBatch) -> Result<()> { - self.db.write_schemas(batch) - } - - fn get_account_seq_num_by_version( - &self, - address: AccountAddress, - version: Version, - ) -> Result { - let (account_state_blob, _proof) = self - .state_store - .get_account_state_with_proof_by_state_root( - address, - self.ledger_store - .get_transaction_info(version)? - .state_root_hash(), - )?; - - // If an account does not exist, we treat it as if it has sequence number 0. - Ok(get_account_resource_or_default(&account_state_blob)?.sequence_number()) - } - - fn get_transaction_with_proof( - &self, - version: Version, - ledger_version: Version, - fetch_events: bool, - ) -> Result { - let proof = { - let (txn_info, txn_info_accumulator_proof) = self - .ledger_store - .get_transaction_info_with_proof(version, ledger_version)?; - SignedTransactionProof::new(txn_info_accumulator_proof, txn_info) - }; - let signed_transaction = self.transaction_store.get_transaction(version)?; - - // If events were requested, also fetch those. - let events = if fetch_events { - Some(self.event_store.get_events_by_version(version)?) - } else { - None - }; - - Ok(SignedTransactionWithProof { - version, - signed_transaction, - events, - proof, - }) - } - } - - // Convert requested range and order to a range in ascending order. - fn get_first_seq_num_and_limit(ascending: bool, cursor: u64, limit: u64) -> Result<(u64, u64)> { - ensure!(limit > 0, "limit should > 0, got {}", limit); - - Ok(if ascending { - (cursor, limit) - } else if limit <= cursor { - (cursor - limit + 1, limit) - } else { - (0, cursor + 1) - }) - } + [MIT](./LICENSE) `), modified: rTabs(` - // Copyright (c) The Libra Core Contributors - // SPDX-License-Identifier: Apache-2.0 + # monaco-react + Monaco Editor for React - //! This crate provides [\`LibraDB\`] which represents physical storage of the core Libra data - //! structures. - //! - //! It relays read/write operations on the physical storage via [\`schemadb\`] to the underlying - //! Key-Value storage system, and implements libra data structures on top of it. + [![NPM](https://nodei.co/npm/@monaco-editor/react.png.png)](https://nodei.co/npm/@monaco-editor/react/) - // Used in other crates for testing. - pub mod mock_genesis; - // Used in this and other crates for testing. - pub mod test_helper; + ## Synopsis - pub mod errors; + Monaco editor wrapper for painless integration with React applications without need of webpack (or other module bundler) configuration files. - mod event_store; - mod ledger_store; - pub mod schema; - mod state_store; - mod transaction_store; + ## Motivation + There is a well-known web technology based code editor called [Monaco Editor](https://microsoft.github.io/monaco-editor/) that powers [VS Code](https://code.visualstudio.com/). [There are also many ways to integrate](https://github.com/Microsoft/monaco-editor-samples/) it provided by monaco creators. But there were tons of problems with integration of monaco with modern technologies; e.g React. - #[cfg(test)] - mod libradb_test; + There also exist solutions for integration with React; e.g [this one](https://github.com/react-monaco-editor/react-monaco-editor) and [this one](https://github.com/jaywcjlove/react-monacoeditor). But they need some custom webpack configuration to make Monaco fully work, which is not the "best" solution for such kind of things like create-react-app - [CRA](https://facebook.github.io/create-react-app/). - use crate::{ - errors::LibraDbError, event_store::EventStore, ledger_store::LedgerStore, schema::*, - state_store::StateStore, transaction_store::TransactionStore, - }; - use crypto::{ - hash::{CryptoHash, SPARSE_MERKLE_PLACEHOLDER_HASH}, - HashValue, - }; - use failure::prelude::*; - use itertools::{izip, zip_eq}; - use lazy_static::lazy_static; - use logger::prelude::*; - use metrics::OpMetrics; - use schemadb::{ColumnFamilyOptions, ColumnFamilyOptionsMap, SchemaBatch, DB, DEFAULT_CF_NAME}; - use std::{iter::Iterator, path::Path, sync::Arc, time::Instant}; - use storage_proto::ExecutorStartupInfo; - use types::{ - access_path::AccessPath, - account_address::AccountAddress, - account_config::get_account_resource_or_default, - account_state_blob::{AccountStateBlob, AccountStateWithProof}, - contract_event::EventWithProof, - get_with_proof::{RequestItem, ResponseItem}, - ledger_info::LedgerInfoWithSignatures, - proof::{AccountStateProof, EventProof, SignedTransactionProof, SparseMerkleProof}, - transaction::{ - SignedTransactionWithProof, TransactionInfo, TransactionListWithProof, TransactionToCommit, - Version, - }, - validator_change::ValidatorChangeEventWithProof, - }; + With this solution, you don't need any kind of webpack configuration files and it works great with React apps created by CRA or created by something else. - lazy_static! { - static ref OP_COUNTER: OpMetrics = OpMetrics::new_and_registered("storage"); + ## Installation + + \`\`\`bash + yarn add @monaco-editor/react # or npm install @monaco-editor/react + \`\`\` + + ## [Demo](https://monaco-react.surenatoyan.com/) + + ## Usage + + Example + \`\`\`js + import React, { useState } from 'react'; + import Editor from '@monaco-editor/react'; + + const examples = { python: '# python example', javascript: '// javascript example' }; + + function App() { + const [theme, setTheme] = useState('light'); + const [language, setLanguage] = useState('javascript'); + const [isEditorReady, setIsEditorReady] = useState(false); + + function handleEditorDidMount() { + setIsEditorReady(true); + } + + function toggleTheme() { + setTheme(theme === 'light' ? 'dark' : 'light'); + } + + function toggleLanguage() { + setLanguage(language === 'javascript' ? 'python' : 'javascript'); + } + + return ( + <> + + + + + + ); } - const MAX_LIMIT: u64 = 1000; - const MAX_REQUEST_ITEMS: u64 = 100; + export default App; + \`\`\` - fn error_if_too_many_requested(num_requested: u64, max_allowed: u64) -> Result<()> { - if num_requested > max_allowed { - Err(LibraDbError::TooManyRequested(num_requested, max_allowed).into()) - } else { - Ok(()) - } - } + #### MonacoEditor instance - /// This holds a handle to the underlying DB responsible for physical storage and provides APIs for - /// access to the core Libra data structures. - pub struct LibraDB { - db: Arc, - ledger_store: LedgerStore, - transaction_store: TransactionStore, - state_store: StateStore, - event_store: EventStore, - } + The second argument of \`editorDidMount\` is the instance of the editor. So, you can use it to get the full control on the editor if you need it. - impl LibraDB { - /// This creates an empty LibraDB instance on disk or opens one if it already exists. - pub fn new + Clone>(db_root_path: P) -> Self { - let cf_opts_map: ColumnFamilyOptionsMap = [ - ( - /* LedgerInfo CF = */ DEFAULT_CF_NAME, - ColumnFamilyOptions::default(), - ), - (ACCOUNT_STATE_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_ACCUMULATOR_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_BY_ACCESS_PATH_CF_NAME, ColumnFamilyOptions::default()), - (EVENT_CF_NAME, ColumnFamilyOptions::default()), - (SIGNATURE_CF_NAME, ColumnFamilyOptions::default()), - (SIGNED_TRANSACTION_CF_NAME, ColumnFamilyOptions::default()), - (STATE_MERKLE_NODE_CF_NAME, ColumnFamilyOptions::default()), - ( - TRANSACTION_ACCUMULATOR_CF_NAME, - ColumnFamilyOptions::default(), - ), - (TRANSACTION_INFO_CF_NAME, ColumnFamilyOptions::default()), - (VALIDATOR_CF_NAME, ColumnFamilyOptions::default()), - ] - .iter() - .cloned() - .collect(); + ## Props - let path = db_root_path.as_ref().join("libradb"); - let instant = Instant::now(); - let db = Arc::new( - DB::open(path.clone(), cf_opts_map) - .unwrap_or_else(|e| panic!("LibraDB open failed: {:?}", e)), - ); + #### Editor - info!( - "Opened LibraDB at {:?} in {} ms", - path, - instant.elapsed().as_millis() - ); + | Name | Type | Default | Description | + |:----------|:-------------|:------|:------| + | value | string || The editor value | + | language | enum: ... | | All languages that are [supported](https://github.com/microsoft/monaco-languages) by monaco-editor | + | editorDidMount | func | noop | **Signature: function(getEditorValue: func, monaco: object) => void**
This function will be called right after monaco editor will be mounted and ready to work. It will get the editor instance as a second argument | + | theme | enum: 'light' \| 'dark' | 'light' | Default themes of monaco | + | line | number | | The line to jump on it | + | width | union: number \| string | '100%' | The width of the editor wrapper | + | height | union: number \| string | '100%' | The height of the editor wrapper | + | loading | union: React element \| string | 'Loading...' | The loading screen before the editor will be loaded | + | options | object | {} | [IEditorOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditoroptions.html) | - LibraDB { - db: Arc::clone(&db), - event_store: EventStore::new(Arc::clone(&db)), - ledger_store: LedgerStore::new(Arc::clone(&db)), - state_store: StateStore::new(Arc::clone(&db)), - transaction_store: TransactionStore::new(Arc::clone(&db)), - } - } + #### DiffEditor - // ================================== Public API ================================== - /// Returns the account state corresponding to the given version and account address with proof - /// based on \`ledger_version\` - fn get_account_state_with_proof( - &self, - address: AccountAddress, - version: Version, - ledger_version: Version, - ) -> Result { - ensure!( - version <= ledger_version, - "The queried version {} should be equal to or older than ledger version {}.", - version, - ledger_version - ); - let latest_version = self.get_latest_version()?; - ensure!( - ledger_version <= latest_version, - "The ledger version {} is greater than the latest version currently in ledger: {}", - ledger_version, - latest_version - ); + | Name | Type | Default | Description | + |:----------|:-------------|:------|:------| + | original | string || The original source (left one) value | + | modified | string || The modified source (right one) value | + | language | enum: ... | | All languages that are [supported](https://github.com/microsoft/monaco-languages) by monaco-editor | + | originalLanguage | enum: ... | *language | This prop gives you the opportunity to specify the language of the \`original\` source separately, otherwise, it will get the value of \`language\` property. (Possible values are the same as \`language\`) | + | modifiedLanguage | enum: ... | *language | This prop gives you the opportunity to specify the language of the \`modified\` source separately, otherwise, it will get the value of \`language\` property. (Possible values are the same as \`language\`) | + | editorDidMount | func | noop | **Signature: function(getOriginalEditorValue: func, getModifiedEditorValue: func, monaco: object) => void**
This function will be called right after monaco editor will be mounted and ready to work. It will get the editor instance as a third argument | + | theme | enum: 'light' \| 'dark' | 'light' | Default themes of monaco | + | line | number | | The line to jump on it | + | width | union: number \| string | '100%' | The width of the editor wrapper | + | height | union: number \| string | '100%' | The height of the editor wrapper | + | loading | union: React element \| string | 'Loading...' | The loading screen before the editor will be loaded | + | options | object | {} | [IDiffEditorOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.idiffeditorconstructionoptions.html) | - let (txn_info, txn_info_accumulator_proof) = self - .ledger_store - .get_transaction_info_with_proof(version, ledger_version)?; - let (account_state_blob, sparse_merkle_proof) = self - .state_store - .get_account_state_with_proof_by_state_root(address, txn_info.state_root_hash())?; - Ok(AccountStateWithProof::new( - version, - account_state_blob, - AccountStateProof::new(txn_info_accumulator_proof, txn_info, sparse_merkle_proof), - )) - } + ## License - /// Returns events specified by \`access_path\` with sequence number in range designated by - /// \`start_seq_num\`, \`ascending\` and \`limit\`. If ascending is true this query will return up to - /// \`limit\` events that were emitted after \`start_event_seq_num\`. Otherwise it will return up to - /// \`limit\` events in the reverse order. Both cases are inclusive. - fn get_events_by_event_access_path( - &self, - access_path: &AccessPath, - start_seq_num: u64, - ascending: bool, - limit: u64, - ledger_version: Version, - ) -> Result<(Vec, Option)> { - error_if_too_many_requested(limit, MAX_LIMIT)?; - - let get_latest = !ascending && start_seq_num == u64::max_value(); - let cursor = if get_latest { - // Caller wants the latest, figure out the latest seq_num. - // In the case of no events on that path, use 0 and expect empty result below. - self.event_store - .get_latest_sequence_number(ledger_version, access_path)? - .unwrap_or(0) - } else { - start_seq_num - }; - - // Convert requested range and order to a range in ascending order. - let (first_seq, real_limit) = get_first_seq_num_and_limit(ascending, cursor, limit)?; - - // Query the index. - let mut event_keys = self.event_store.lookup_events_by_access_path( - access_path, - first_seq, - real_limit, - ledger_version, - )?; - - // When descending, it's possible that user is asking for something beyond the latest - // sequence number, in which case we will consider it a bad request and return an empty - // list. - // For example, if the latest sequence number is 100, and the caller is asking for 110 to - // 90, we will get 90 to 100 from the index lookup above. Seeing that the last item - // is 100 instead of 110 tells us 110 is out of bound. - if !ascending { - if let Some((seq_num, _, _)) = event_keys.last() { - if *seq_num < cursor { - event_keys = Vec::new(); - } - } - } - - let mut events_with_proof = event_keys - .into_iter() - .map(|(seq, ver, idx)| { - let (event, event_proof) = self - .event_store - .get_event_with_proof_by_version_and_index(ver, idx)?; - ensure!( - seq == event.sequence_number(), - "Index broken, expected seq:{}, actual:{}", - seq, - event.sequence_number() - ); - let (txn_info, txn_info_proof) = self - .ledger_store - .get_transaction_info_with_proof(ver, ledger_version)?; - let proof = EventProof::new(txn_info_proof, txn_info, event_proof); - Ok(EventWithProof::new(ver, idx, event, proof)) - }) - .collect::>>()?; - if !ascending { - events_with_proof.reverse(); - } - - // There are two cases where we need to return proof_of_latest_event to let the caller know - // the latest sequence number: - // 1. The user asks for the latest event by using u64::max() as the cursor, apparently - // he doesn't know the latest sequence number. - // 2. We are going to return less than \`real_limit\` items. (Two cases can lead to that: - // a. the cursor is beyond the latest sequence number; b. in ascending order we don't have - // enough items to return because the latest sequence number is hit). In this case we - // need to return the proof to convince the caller we didn't hide any item from him. Note - // that we use \`real_limit\` instead of \`limit\` here because it takes into account the case - // of hitting 0 in descending order, which is valid and doesn't require the proof. - let proof_of_latest_event = if get_latest || events_with_proof.len() < real_limit as usize { - Some(self.get_account_state_with_proof( - access_path.address, - ledger_version, - ledger_version, - )?) - } else { - None - }; - - Ok((events_with_proof, proof_of_latest_event)) - } - - /// Returns a signed transaction that is the \`seq_num\`-th one associated with the given account. - /// If the signed transaction with given \`seq_num\` doesn't exist, returns \`None\`. - // TODO(gzh): Use binary search for now. We may create seq_num index in the future. - fn get_txn_by_account_and_seq( - &self, - address: AccountAddress, - seq_num: u64, - ledger_version: Version, - fetch_events: bool, - ) -> Result> { - // If txn with seq_num n is at some version, the corresponding account state at the - // same version will be the first account state that has seq_num n + 1. - let seq_num = seq_num + 1; - let (mut start_version, mut end_version) = (0, ledger_version); - while start_version < end_version { - let mid_version = start_version + (end_version - start_version) / 2; - let account_seq_num = self.get_account_seq_num_by_version(address, mid_version)?; - if account_seq_num >= seq_num { - end_version = mid_version; - } else { - start_version = mid_version + 1; - } - } - assert_eq!(start_version, end_version); - - let seq_num_found = self.get_account_seq_num_by_version(address, start_version)?; - if seq_num_found < seq_num { - return Ok(None); - } else if seq_num_found > seq_num { - // log error - bail!("internal error: seq_num is not continuous.") - } - // start_version cannot be 0 (genesis version). - assert_eq!( - self.get_account_seq_num_by_version(address, start_version - 1)?, - seq_num_found - 1 - ); - self.get_transaction_with_proof(start_version, ledger_version, fetch_events) - .map(Some) - } - - /// Gets the latest version number available in the ledger. - fn get_latest_version(&self) -> Result { - Ok(self - .ledger_store - .get_latest_ledger_info()? - .ledger_info() - .version()) - } - - /// Persist transactions. Called by the executor module when either syncing nodes or committing - /// blocks during normal operation. - /// - /// When \`ledger_info_with_sigs\` is provided, verify that the transaction accumulator root hash - /// it carries is generated after the \`txns_to_commit\` are applied. - pub fn save_transactions( - &self, - txns_to_commit: &[TransactionToCommit], - first_version: Version, - ledger_info_with_sigs: &Option, - ) -> Result<()> { - let num_txns = txns_to_commit.len() as u64; - // ledger_info_with_sigs could be None if we are doing state synchronization. In this case - // txns_to_commit should not be empty. Otherwise it is okay to commit empty blocks. - ensure!( - ledger_info_with_sigs.is_some() || num_txns > 0, - "txns_to_commit is empty while ledger_info_with_sigs is None.", - ); - - let cur_state_root_hash = if first_version == 0 { - *SPARSE_MERKLE_PLACEHOLDER_HASH - } else { - self.ledger_store - .get_transaction_info(first_version - 1)? - .state_root_hash() - }; - - if let Some(x) = ledger_info_with_sigs { - let last_version = x.ledger_info().version(); - ensure!( - first_version + num_txns - 1 == last_version, - "Transaction batch not applicable: first_version {}, num_txns {}, last_version {}", - first_version, - num_txns, - last_version - ); - } - - // Gather db mutations to \`batch\`. - let mut batch = SchemaBatch::new(); - - let new_root_hash = self.save_transactions_impl( - txns_to_commit, - first_version, - cur_state_root_hash, - &mut batch, - )?; - - // If expected ledger info is provided, verify result root hash and save the ledger info. - if let Some(x) = ledger_info_with_sigs { - let expected_root_hash = x.ledger_info().transaction_accumulator_hash(); - ensure!( - new_root_hash == expected_root_hash, - "Root hash calculated doesn't match expected. {:?} vs {:?}", - new_root_hash, - expected_root_hash, - ); - - self.ledger_store.put_ledger_info(x, &mut batch)?; - } - - // Persist. - self.commit(batch)?; - // Only increment counter if commit(batch) succeeds. - OP_COUNTER.inc_by("committed_txns", txns_to_commit.len()); - Ok(()) - } - - fn save_transactions_impl( - &self, - txns_to_commit: &[TransactionToCommit], - first_version: u64, - cur_state_root_hash: HashValue, - mut batch: &mut SchemaBatch, - ) -> Result { - let last_version = first_version + txns_to_commit.len() as u64 - 1; - - // Account state updates. Gather account state root hashes - let account_state_sets = txns_to_commit - .iter() - .map(|txn_to_commit| txn_to_commit.account_states().clone()) - .collect::>(); - let state_root_hashes = self.state_store.put_account_state_sets( - account_state_sets, - cur_state_root_hash, - &mut batch, - )?; - - // Event updates. Gather event accumulator root hashes. - let event_root_hashes = zip_eq(first_version..=last_version, txns_to_commit) - .map(|(ver, txn_to_commit)| { - self.event_store - .put_events(ver, txn_to_commit.events(), &mut batch) - }) - .collect::>>()?; - - // Transaction updates. Gather transaction hashes. - zip_eq(first_version..=last_version, txns_to_commit) - .map(|(ver, txn_to_commit)| { - self.transaction_store - .put_transaction(ver, txn_to_commit.signed_txn(), &mut batch) - }) - .collect::>()?; - let txn_hashes = txns_to_commit - .iter() - .map(|txn_to_commit| txn_to_commit.signed_txn().hash()) - .collect::>(); - let gas_amounts = txns_to_commit - .iter() - .map(TransactionToCommit::gas_used) - .collect::>(); - - // Transaction accumulator updates. Get result root hash. - let txn_infos = izip!( - txn_hashes, - state_root_hashes, - event_root_hashes, - gas_amounts - ) - .map(|(t, s, e, g)| TransactionInfo::new(t, s, e, g)) - .collect::>(); - assert_eq!(txn_infos.len(), txns_to_commit.len()); - - let new_root_hash = - self.ledger_store - .put_transaction_infos(first_version, &txn_infos, &mut batch)?; - - Ok(new_root_hash) - } - - /// This backs the \`UpdateToLatestLedger\` public read API which returns the latest - /// [\`LedgerInfoWithSignatures\`] together with items requested and proofs relative to the same - /// ledger info. - pub fn update_to_latest_ledger( - &self, - _client_known_version: u64, - request_items: Vec, - ) -> Result<( - Vec, - LedgerInfoWithSignatures, - Vec, - )> { - error_if_too_many_requested(request_items.len() as u64, MAX_REQUEST_ITEMS)?; - - // Get the latest ledger info and signatures - let ledger_info_with_sigs = self.ledger_store.get_latest_ledger_info()?; - let ledger_version = ledger_info_with_sigs.ledger_info().version(); - - // Fulfill all request items - let response_items = request_items - .into_iter() - .map(|request_item| match request_item { - RequestItem::GetAccountState { address } => Ok(ResponseItem::GetAccountState { - account_state_with_proof: self.get_account_state_with_proof( - address, - ledger_version, - ledger_version, - )?, - }), - RequestItem::GetAccountTransactionBySequenceNumber { - account, - sequence_number, - fetch_events, - } => { - let signed_transaction_with_proof = self.get_txn_by_account_and_seq( - account, - sequence_number, - ledger_version, - fetch_events, - )?; - - let proof_of_current_sequence_number = match signed_transaction_with_proof { - Some(_) => None, - None => Some(self.get_account_state_with_proof( - account, - ledger_version, - ledger_version, - )?), - }; - - Ok(ResponseItem::GetAccountTransactionBySequenceNumber { - signed_transaction_with_proof, - proof_of_current_sequence_number, - }) - } - - RequestItem::GetEventsByEventAccessPath { - access_path, - start_event_seq_num, - ascending, - limit, - } => { - let (events_with_proof, proof_of_latest_event) = self - .get_events_by_event_access_path( - &access_path, - start_event_seq_num, - ascending, - limit, - ledger_version, - )?; - Ok(ResponseItem::GetEventsByEventAccessPath { - events_with_proof, - proof_of_latest_event, - }) - } - RequestItem::GetTransactions { - start_version, - limit, - fetch_events, - } => { - let txn_list_with_proof = - self.get_transactions(start_version, limit, ledger_version, fetch_events)?; - - Ok(ResponseItem::GetTransactions { - txn_list_with_proof, - }) - } - }) - .collect::>>()?; - - Ok(( - response_items, - ledger_info_with_sigs, - vec![], /* TODO: validator_change_events */ - )) - } - - // =========================== Execution Internal APIs ======================================== - - /// Gets an account state by account address, out of the ledger state indicated by the state - /// Merkle tree root hash. - /// - /// This is used by the executor module internally. - pub fn get_account_state_with_proof_by_state_root( - &self, - address: AccountAddress, - state_root: HashValue, - ) -> Result<(Option, SparseMerkleProof)> { - self.state_store - .get_account_state_with_proof_by_state_root(address, state_root) - } - - /// Gets information needed from storage during the startup of the executor module. - /// - /// This is used by the executor module internally. - pub fn get_executor_startup_info(&self) -> Result> { - // Get the latest ledger info. Return None if not bootstrapped. - let ledger_info_with_sigs = match self.ledger_store.get_latest_ledger_info_option()? { - Some(x) => x, - None => return Ok(None), - }; - let ledger_info = ledger_info_with_sigs.ledger_info().clone(); - - let (latest_version, txn_info) = self.ledger_store.get_latest_transaction_info()?; - - let account_state_root_hash = txn_info.state_root_hash(); - - let ledger_frozen_subtree_hashes = self - .ledger_store - .get_ledger_frozen_subtree_hashes(latest_version)?; - - Ok(Some(ExecutorStartupInfo { - ledger_info, - latest_version, - account_state_root_hash, - ledger_frozen_subtree_hashes, - })) - } - - // ======================= State Synchronizer Internal APIs =================================== - /// Gets a batch of transactions for the purpose of synchronizing state to another node. - /// - /// This is used by the State Synchronizer module internally. - pub fn get_transactions( - &self, - start_version: Version, - limit: u64, - ledger_version: Version, - fetch_events: bool, - ) -> Result { - error_if_too_many_requested(limit, MAX_LIMIT)?; - - if start_version > ledger_version || limit == 0 { - return Ok(TransactionListWithProof::new_empty()); - } - - let limit = std::cmp::min(limit, ledger_version - start_version + 1); - let txn_and_txn_info_list = (start_version..start_version + limit) - .into_iter() - .map(|version| { - Ok(( - self.transaction_store.get_transaction(version)?, - self.ledger_store.get_transaction_info(version)?, - )) - }) - .collect::>>()?; - let proof_of_first_transaction = Some( - self.ledger_store - .get_transaction_proof(start_version, ledger_version)?, - ); - let proof_of_last_transaction = if limit == 1 { - None - } else { - Some( - self.ledger_store - .get_transaction_proof(start_version + limit - 1, ledger_version)?, - ) - }; - let events = if fetch_events { - Some( - (start_version..start_version + limit) - .into_iter() - .map(|version| Ok(self.event_store.get_events_by_version(version)?)) - .collect::>>()?, - ) - } else { - None - }; - - Ok(TransactionListWithProof::new( - txn_and_txn_info_list, - events, - Some(start_version), - proof_of_first_transaction, - proof_of_last_transaction, - )) - } - - // ================================== Private APIs ================================== - /// Write the whole schema batch including all data necessary to mutate the ledge - /// state of some transaction by leveraging rocksdb atomicity support. - fn commit(&self, batch: SchemaBatch) -> Result<()> { - self.db.write_schemas(batch)?; - - match self.db.get_approximate_sizes_cf() { - Ok(cf_sizes) => { - for (cf_name, size) in cf_sizes { - OP_COUNTER.set(&format!("cf_size_bytes_{}", cf_name), size as usize); - } - } - Err(err) => warn!( - "Failed to get approximate size of column families: {}.", - err - ), - } - - Ok(()) - } - - fn get_account_seq_num_by_version( - &self, - address: AccountAddress, - version: Version, - ) -> Result { - let (account_state_blob, _proof) = self - .state_store - .get_account_state_with_proof_by_state_root( - address, - self.ledger_store - .get_transaction_info(version)? - .state_root_hash(), - )?; - - // If an account does not exist, we treat it as if it has sequence number 0. - Ok(get_account_resource_or_default(&account_state_blob)?.sequence_number()) - } - - fn get_transaction_with_proof( - &self, - version: Version, - ledger_version: Version, - fetch_events: bool, - ) -> Result { - let proof = { - let (txn_info, txn_info_accumulator_proof) = self - .ledger_store - .get_transaction_info_with_proof(version, ledger_version)?; - SignedTransactionProof::new(txn_info_accumulator_proof, txn_info) - }; - let signed_transaction = self.transaction_store.get_transaction(version)?; - - // If events were requested, also fetch those. - let events = if fetch_events { - Some(self.event_store.get_events_by_version(version)?) - } else { - None - }; - - Ok(SignedTransactionWithProof { - version, - signed_transaction, - events, - proof, - }) - } - } - - // Convert requested range and order to a range in ascending order. - fn get_first_seq_num_and_limit(ascending: bool, cursor: u64, limit: u64) -> Result<(u64, u64)> { - ensure!(limit > 0, "limit should > 0, got {}", limit); - - Ok(if ascending { - (cursor, limit) - } else if limit <= cursor { - (cursor - limit + 1, limit) - } else { - (0, cursor + 1) - }) - } + [MIT](./LICENSE) `), }; diff --git a/demo/src/store/state/index.js b/demo/src/store/state/index.js index 87fc3fc..6a469e9 100644 --- a/demo/src/store/state/index.js +++ b/demo/src/store/state/index.js @@ -71,7 +71,7 @@ const initialState = { }, diffEditor: { - selectedLanguageId: 43, // 43 is the id of rust + selectedLanguageId: 24, // 24 is the id of markdown }, }; diff --git a/demo/yarn.lock b/demo/yarn.lock index b58ccce..b18246b 100644 --- a/demo/yarn.lock +++ b/demo/yarn.lock @@ -926,14 +926,20 @@ integrity sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A== "@hapi/joi@^15.0.0": - version "15.0.3" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.0.3.tgz#e94568fd859e5e945126d5675e7dd218484638a7" - integrity sha512-z6CesJ2YBwgVCi+ci8SI8zixoj8bGFn/vZb9MBPbSyoxsS2PnWYjHcyTM17VLK6tx64YVK38SDIh10hJypB+ig== + version "15.1.0" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.0.tgz#940cb749b5c55c26ab3b34ce362e82b6162c8e7a" + integrity sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ== dependencies: "@hapi/address" "2.x.x" "@hapi/hoek" "6.x.x" + "@hapi/marker" "1.x.x" "@hapi/topo" "3.x.x" +"@hapi/marker@1.x.x": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@hapi/marker/-/marker-1.0.0.tgz#65b0b2b01d1be06304886ce9b4b77b1bfb21a769" + integrity sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA== + "@hapi/topo@3.x.x": version "3.1.0" resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.0.tgz#5c47cd9637c2953db185aa957a27bcb2a8b7a6f8" @@ -1088,14 +1094,15 @@ "@types/yargs" "^12.0.9" "@material-ui/core@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.1.1.tgz#11e703f3d44d84750c9b829f13bb08ad8949e12a" - integrity sha512-dZVuVFqKnG3uf+s32U5wMTAXYBGBM6e2LF4fz4ud9woaYcthRiEFJTg2idt0j1jBMg99gqLuznR5+A9TCQbgxQ== + version "4.1.2" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.1.2.tgz#395eeeb7e24d77bec58f586577221617a5b3d368" + integrity sha512-qW0RmqMAenccFF6ErUPixDTi2hjboKU7PxaDB4OhFmDACBU8kWTf9XCoFzBVXwO3ADDkgpUTfBFNf9y2H9oubQ== dependencies: "@babel/runtime" "^7.2.0" - "@material-ui/styles" "^4.1.1" - "@material-ui/system" "^4.2.0" - "@material-ui/types" "^4.1.0" + "@material-ui/react-transition-group" "^4.2.0" + "@material-ui/styles" "^4.1.2" + "@material-ui/system" "^4.3.0" + "@material-ui/types" "^4.1.1" "@material-ui/utils" "^4.1.0" "@types/react-transition-group" "^2.0.16" clsx "^1.0.2" @@ -1108,35 +1115,45 @@ popper.js "^1.14.1" prop-types "^15.7.2" react-event-listener "^0.6.6" - react-transition-group "^4.0.0" warning "^4.0.1" "@material-ui/icons@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.2.0.tgz#cd0b6521288c5e6c0b084d6defec37a4491e0c51" - integrity sha512-v+rz61KzH+qR8x17BrfOF73f75x+wUNiBhv9tsKnEed+ElROMK2dqfMAlsdgEP+wgGl4VOcxzUQqWHcaApZ+CA== + version "4.2.1" + resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.2.1.tgz#fe2f1c4f60c24256d244a69d86d0c00e8ed4037e" + integrity sha512-FvSD5lUBJ66frI4l4AYAPy2CH14Zs2Dgm0o3oOMr33BdQtOAjCgbdOcvPBeaD1w6OQl31uNW3CKOE8xfPNxvUQ== dependencies: "@babel/runtime" "^7.2.0" "@material-ui/lab@^4.0.0-alpha.16": - version "4.0.0-alpha.16" - resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.16.tgz#0d5f4e7e7eda057b732d26fe603b38cce6adf3b2" - integrity sha512-NKaIMQd9bUI+Iny6AduYA0KBkVq5XAVWspNtem4qmPTr4aFbh90IZ1a8twN77hHHJm35MRBy4Sq+Y7I07JGw0g== + version "4.0.0-alpha.17" + resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.17.tgz#06fd70066f70a1e8f0d084a59cdd62ee8559d2df" + integrity sha512-DMbOI62uf2XEn1SgA8XevggK/s64XOLxZUo9YYPqzH9orh5i647ND61cehKWeDtCHD85Q9tSJZ0YGI7givKvVA== dependencies: "@babel/runtime" "^7.2.0" "@material-ui/utils" "^4.1.0" clsx "^1.0.2" keycode "^2.1.9" prop-types "^15.7.2" + warning "^4.0.1" -"@material-ui/styles@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.1.1.tgz#16e9d4770bd18b85c25fd3cb925043af5fa37f36" - integrity sha512-BmtfLRY0CqAkYPdcFmNcD1/zyU6ATRx9vaBxJ31//YVxfRsyPOuQXW6fvAoDvQt/hbZpTR4E0K/+4D3wHHTdHQ== +"@material-ui/react-transition-group@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@material-ui/react-transition-group/-/react-transition-group-4.2.0.tgz#afec833bbcc79f05a9b4d4828b3e07965cc7e321" + integrity sha512-4zapZ0gW1ZTws5aH9OGy3IMvtTV/olc7YrVSkM1WFu1FsrEhL+qarEniRjx7LjHt0gukFqoINfElI8v2boVMQA== + dependencies: + "@babel/runtime" "^7.4.5" + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + +"@material-ui/styles@^4.1.1", "@material-ui/styles@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.1.2.tgz#f22cb0d8f60a5e4a4b92f1ffb4b56f825ff89034" + integrity sha512-IRwhGI3OzxMKIDXnYl/vi9FD/i5ZktVP2m/5PIf/HVdvhqUZGIzqR2OB/9f3W1hc+kKKExdOPlpZpVihIsJWkA== dependencies: "@babel/runtime" "^7.2.0" "@emotion/hash" "^0.7.1" - "@material-ui/types" "^4.1.0" + "@material-ui/types" "^4.1.1" "@material-ui/utils" "^4.1.0" clsx "^1.0.2" csstype "^2.5.2" @@ -1153,20 +1170,22 @@ prop-types "^15.7.2" warning "^4.0.1" -"@material-ui/system@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.2.0.tgz#1c0759f1168bf871a7970239dc781b7bf9dfd010" - integrity sha512-t51525FWVDjca/3UPwN99vqyvbfGNtBVesGYH2UpxVgKOdiP1ZINeHhBrZ8h4uOu5ZwgO4aceuk1TuM9uMttYw== +"@material-ui/system@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.3.0.tgz#6812049bf9257f8936c5de8f18b7142a67048247" + integrity sha512-VQh3mWZSmzm1JR7Ci35AHKwOhhxHHMrBWCdP4mh7UAwSdjWBE6s2Y9Y0iJiqMoEsHP64vU3W1JpsW2AgkUeHsQ== dependencies: "@babel/runtime" "^7.2.0" deepmerge "^3.0.0" prop-types "^15.7.2" warning "^4.0.1" -"@material-ui/types@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-4.1.0.tgz#58e60d86f5a554e60c06a4a91f2030ac2c56a5fd" - integrity sha512-F4z7GOAeEucPjrrhJ2PHBhMZjhggE6Jjnzmap5W2PdZ3TSWNlqucB+oOzT6EzWRkHDDhVmANMU8QMfT/kcZtOg== +"@material-ui/types@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-4.1.1.tgz#b65e002d926089970a3271213a3ad7a21b17f02b" + integrity sha512-AN+GZNXytX9yxGi0JOfxHrRTbhFybjUJ05rnsBVjcB+16e466Z0Xe5IxawuOayVZgTBNDxmPKo5j4V6OnMtaSQ== + dependencies: + "@types/react" "*" "@material-ui/utils@^4.1.0": version "4.1.0" @@ -1177,10 +1196,10 @@ prop-types "^15.7.2" react-is "^16.8.0" -"@monaco-editor/react@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-0.0.1.tgz#21d9bd084c77fe1cfdf4157b881436a084ed7304" - integrity sha512-ngu39bak1ehNiIzZZQ5L3wbmHl8KcVC+Ww8I1q8Jh8tG8JMxGNewZsGu9sztazozn4kq0lK0utNBJWh96pCVGA== +"@monaco-editor/react@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-1.0.1.tgz#1f808abc55bcc9228df90db3db4cfd1e15a4988b" + integrity sha512-GePWyyO7BUOeIBbBZG95k0AF4BbFxg7wtZ8n2+QyDkfEzHWXYaSKlaBDtXtZmeWRj75H9zaiGbejp5DLzvzJ2Q== "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -1354,14 +1373,14 @@ "@types/istanbul-lib-report" "*" "@types/node@*": - version "12.0.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.8.tgz#551466be11b2adc3f3d47156758f610bd9f6b1d8" - integrity sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg== + version "12.0.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.10.tgz#51babf9c7deadd5343620055fc8aff7995c8b031" + integrity sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ== "@types/node@^10.5.1": - version "10.14.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.9.tgz#2e8d678039d27943ce53a1913386133227fd9066" - integrity sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg== + version "10.14.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.10.tgz#e491484c6060af8d461e12ec81c0da8a3282b8de" + integrity sha512-V8wj+w2YMNvGuhgl/MA5fmTxgjmVHVoasfIaxMMZJV6Y8Kk+Ydpi1z2whoShDCJ2BuNVoqH/h1hrygnBxkrw/Q== "@types/prop-types@*": version "15.7.1" @@ -1381,9 +1400,9 @@ "@types/react" "*" "@types/react@*": - version "16.8.21" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.21.tgz#aefb32519a4111964993be5b2bd3f172f81c34ff" - integrity sha512-+jAtgtJ3htE+VEP/bMzBBOANGkaTbMOGYWVrmhCVtp2WE//lNG6Irw9kBEaLR7lQGjjkt/BlSSHPgArFNOKhkg== + version "16.8.22" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.22.tgz#7f18bf5ea0c1cad73c46b6b1c804a3ce0eec6d54" + integrity sha512-C3O1yVqk4sUXqWyx0wlys76eQfhrQhiDhDlHBrjER76lR2S2Agiid/KpOU9oCqj1dISStscz7xXz1Cg8+sCQeA== dependencies: "@types/prop-types" "*" csstype "^2.2.0" @@ -2317,9 +2336,9 @@ browserslist@^4.0.0, browserslist@^4.1.1, browserslist@^4.4.2, browserslist@^4.5 node-releases "^1.1.23" bser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" - integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= + version "2.1.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5" + integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg== dependencies: node-int64 "^0.4.0" @@ -2455,9 +2474,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000955, caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000975: - version "1.0.30000975" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000975.tgz#d4e7131391dddcf2838999d3ce75065f65f1cdfc" - integrity sha512-ZsXA9YWQX6ATu5MNg+Vx/cMQ+hM6vBBSqDeJs8ruk9z0ky4yIHML15MoxcFt088ST2uyjgqyUGRJButkptWf0w== + version "1.0.30000977" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000977.tgz#7da2ca14cae2fddb368c05c57ab4a529afd658ff" + integrity sha512-RTXL32vdfAc2g9aoDL6vnBzbOO/3sM+T+YX4m7W9iFZnl3qIz7WYoZZpcZpALud8xq4+N56rnruX/NQy9HQu6A== capture-exit@^2.0.0: version "2.0.0" @@ -3049,9 +3068,9 @@ css-url-regex@^1.1.0: integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= css-vendor@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.4.tgz#c605f4c17f454e4ad1db206e04128da1da1d31dd" - integrity sha512-ITGWQoPfgHTxZYMYm/OXTxqz+nkG1LHW6xDQYdEUC+/EGbxB4Kg4nR6HutU98DdWmC7G+tPXUvoEmwi30B9HAA== + version "2.0.5" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.5.tgz#949c58fd5307e79a9417daa0939506f0e5d0a187" + integrity sha512-36w+4Cg0zqFIt5TAkaM3proB6XWh5kSGmbddRCPdrRLQiYNfHPTgaWPOlCrcuZIO0iAtrG+5wsHJZ6jj8AUULA== dependencies: "@babel/runtime" "^7.3.1" is-in-browser "^1.0.2" @@ -3258,9 +3277,9 @@ deep-is@~0.1.3: integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= deepmerge@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.1.tgz#76a1f47854bcfcd66ee9a948d110540a8e12b261" - integrity sha512-+hbDSzTqEW0fWgnlKksg7XAOtT+ddZS5lHZJ6f6MdixRs9wQy+50fm1uUCVb1IkvjLUYX/SfFO021ZNwriURTw== + version "3.3.0" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.3.0.tgz#d3c47fd6f3a93d517b14426b0628a17b0125f5f7" + integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== default-gateway@^4.2.0: version "4.2.0" @@ -3534,9 +3553,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.122, electron-to-chromium@^1.3.164: - version "1.3.166" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.166.tgz#99d267514f4b92339788172400bc527545deb75b" - integrity sha512-7XwtJz81H/PBnkmQ/07oVPOGTkBZs6ibZN8OqXNUrxjRPzR0Xj+MFcMmRZEXGilEg1Pm+97V8BZVI63qnBX1hQ== + version "1.3.173" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.173.tgz#275b9ba235447b95fc3204d32ca2c5a8bf2ca599" + integrity sha512-weH16m8as+4Fy4XJxrn/nFXsIqB7zkxERhvj/5YX2HE4HB8MCu98Wsef4E3mu0krIT27ic0bGsr+TvqYrUn6Qg== elliptic@^6.0.0: version "6.4.1" @@ -3716,9 +3735,9 @@ eslint-plugin-jsx-a11y@6.2.1: jsx-ast-utils "^2.0.1" eslint-plugin-react-hooks@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.0.tgz#348efcda8fb426399ac7b8609607c7b4025a6f5f" - integrity sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag== + version "1.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz#3c66a5515ea3e0a221ffc5d4e75c971c217b1a4c" + integrity sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA== eslint-plugin-react@7.12.4: version "7.12.4" @@ -4705,7 +4724,7 @@ http-deceiver@^1.2.7: resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= -http-errors@1.7.2, http-errors@~1.7.2: +http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== @@ -4726,6 +4745,17 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + "http-parser-js@>=0.4.0 <0.4.11": version "0.4.10" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" @@ -4883,7 +4913,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4923,9 +4953,9 @@ inquirer@6.2.2: through "^2.3.6" inquirer@^6.2.2: - version "6.4.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.4.0.tgz#6f9284047c4e48b76b169e46b3ae3b2171ce30a2" - integrity sha512-O3qJQ+fU/AI1K2y5/RjqefMEQTdJQf6sPTvyRA1bx6D634ADxcu97u6YOUciIeU2OWIuvpUsQs6Wx3Fdi3eFaQ== + version "6.4.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.4.1.tgz#7bd9e5ab0567cd23b41b0180b68e0cfa82fc3c0b" + integrity sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw== dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -6427,9 +6457,9 @@ mississippi@^3.0.0: through2 "^2.0.0" mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -7359,11 +7389,11 @@ postcss-custom-media@^7.0.7: postcss "^7.0.14" postcss-custom-properties@^8.0.9: - version "8.0.10" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.10.tgz#e8dc969e1e15c555f0b836b7f278ef47e3cdeaff" - integrity sha512-GDL0dyd7++goDR4SSasYdRNNvp4Gqy1XMzcCnTijiph7VB27XXpJ8bW/AI0i2VSBZ55TpdGhMr37kMSpRfYD0Q== + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== dependencies: - postcss "^7.0.14" + postcss "^7.0.17" postcss-values-parser "^2.0.1" postcss-custom-selectors@^5.1.2: @@ -7902,7 +7932,7 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6: version "7.0.17" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== @@ -8286,16 +8316,6 @@ react-scripts@3.0.1: optionalDependencies: fsevents "2.0.6" -react-transition-group@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.1.1.tgz#16efe9ac8c68306f6bef59c7da5a96b4dfd9fb32" - integrity sha512-K/N1wqJ2GRP2yj3WBqEUYa0KV5fiaAWpUfU9SpHOHefeKvyrO+VrnMBML21M19QZoVbDZKmuQFHZYoMMi1xuJA== - dependencies: - "@babel/runtime" "^7.4.5" - dom-helpers "^3.4.0" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react@^16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" @@ -8603,9 +8623,9 @@ resolve@1.10.0: path-parse "^1.0.6" resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" - integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw== + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== dependencies: path-parse "^1.0.6" @@ -8774,9 +8794,9 @@ semver@6.0.0: integrity sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ== semver@^6.0.0, semver@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b" - integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ== + version "6.1.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.2.tgz#079960381376a3db62eb2edc8a3bfb10c7cfe318" + integrity sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ== send@0.17.1: version "0.17.1" @@ -8830,20 +8850,10 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -9678,14 +9688,14 @@ unified@^7.1.0: x-is-string "^0.1.0" union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" get-value "^2.0.6" is-extendable "^0.1.1" - set-value "^0.4.3" + set-value "^2.0.1" uniq@^1.0.1: version "1.0.1"