-
Notifications
You must be signed in to change notification settings - Fork 405
Refactor on the core observable engine #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
af22931
First.
jamesdaniels 5cdd030
Cleanup and comments
jamesdaniels 9a29caf
Better warm up on the subscription, fix test script, and useState/set…
jamesdaniels c423a30
Firestore is green
jamesdaniels 2c4b25f
Green tests
jamesdaniels cf14caa
Catch the error in the observable, immediately clean up cache on unsu…
jamesdaniels c6e0f32
Removing unneeded changes
jamesdaniels 59a0882
Rename to SuspenseSubject
jamesdaniels a82d9f1
Clean up observable caching ids more, also collection() doesnt take i…
jamesdaniels 8ac5b1f
NPM pack for easier local testing and .npmignore test files
jamesdaniels 778b297
Case sensitive FS on Travis
jamesdaniels 81064d2
Cache remote config off of appName and getter
jamesdaniels 7e78f0a
fail, if there isnt a throw
jamesdaniels 71adcb1
Start typing FirebaseAppProvider props, allow more than one app, erro…
jamesdaniels a321083
Addressing my own nits
jamesdaniels File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| [debug] [2020-02-07T01:39:18.184Z] ---------------------------------------------------------------------- | ||
| [debug] [2020-02-07T01:39:18.186Z] Command: /Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin/node /Users/jamesdaniels/Code/reactfire/reactfire/node_modules/.bin/firebase emulators:exec --only firestore,database jest --no-cache --verbose --detectOpenHandles --forceExit | ||
| [debug] [2020-02-07T01:39:18.186Z] CLI Version: 7.12.1 | ||
| [debug] [2020-02-07T01:39:18.186Z] Platform: darwin | ||
| [debug] [2020-02-07T01:39:18.186Z] Node Version: v10.15.3 | ||
| [debug] [2020-02-07T01:39:18.187Z] Time: Thu Feb 06 2020 17:39:18 GMT-0800 (Pacific Standard Time) | ||
| [debug] [2020-02-07T01:39:18.187Z] ---------------------------------------------------------------------- | ||
| [debug] [2020-02-07T01:39:18.187Z] | ||
| [debug] [2020-02-07T01:39:18.196Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] | ||
| [debug] [2020-02-07T01:39:18.196Z] > authorizing via signed-in user | ||
| [warn] ⚠ Could not find config (firebase.json) so using defaults. | ||
| [info] i emulators: Starting emulators: firestore, database | ||
| [warn] ⚠ No Firestore rules file specified in firebase.json, using default rules. | ||
| [info] i firestore: Serving ALL traffic (including WebChannel) on http://localhost:8080 | ||
| [warn] ⚠ firestore: Support for WebChannel on a separate port (8081) is DEPRECATED and will go away soon. Please use port above instead. | ||
| [debug] [2020-02-07T01:39:18.261Z] Ignoring unsupported arg: projectId | ||
| [debug] [2020-02-07T01:39:18.261Z] Ignoring unsupported arg: auto_download | ||
| [debug] [2020-02-07T01:39:18.261Z] Starting emulator firestore with command {"binary":"java","args":["-Duser.language=en","-jar","/Users/jamesdaniels/.cache/firebase/emulators/cloud-firestore-emulator-v1.10.2.jar","--host","localhost","--port",8080,"--webchannel_port",8081],"optionalArgs":["port","webchannel_port","host","rules","functions_emulator"],"joinArgs":false} | ||
| [info] i firestore: Emulator logging to firestore-debug.log | ||
| [debug] [2020-02-07T01:39:19.679Z] API endpoint: http://localhost | ||
| [debug] [2020-02-07T01:39:19.679Z] :8080 | ||
| If you are using a library that supports the FIRESTORE_EMULATOR_HOST environment variable, run: | ||
|
|
||
| export FIRESTORE_EMULATOR_HOST=localhost:8080 | ||
|
|
||
| Dev App Server is now running. | ||
|
|
||
|
|
||
| [info] ✔ firestore: Emulator started at http://localhost:8080 | ||
| [info] i firestore: For testing set FIRESTORE_EMULATOR_HOST=localhost:8080 | ||
| [warn] ⚠ No Database rules file specified in firebase.json, using default rules. | ||
| [debug] [2020-02-07T01:39:19.809Z] Ignoring unsupported arg: projectId | ||
| [debug] [2020-02-07T01:39:19.810Z] Ignoring unsupported arg: auto_download | ||
| [debug] [2020-02-07T01:39:19.810Z] Starting emulator database with command {"binary":"java","args":["-Duser.language=en","-jar","/Users/jamesdaniels/.cache/firebase/emulators/firebase-database-emulator-v4.3.1.jar","--host","localhost","--port",9000],"optionalArgs":["port","host","functions_emulator_port","functions_emulator_host"],"joinArgs":false} | ||
| [info] i database: Emulator logging to database-debug.log | ||
| [debug] [2020-02-07T01:39:20.698Z] WARNING: An illegal reflective access operation has occurred | ||
| WARNING: Illegal reflective access by io.netty.util.internal.ReflectionUtil (file:/Users/jamesdaniels/.cache/firebase/emulators/firebase-database-emulator-v4.3.1.jar) to field sun.nio.ch.SelectorImpl.selectedKeys | ||
| WARNING: Please consider reporting this to the maintainers of io.netty.util.internal.ReflectionUtil | ||
| WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations | ||
| WARNING: All illegal access operations will be denied in a future release | ||
|
|
||
| [debug] [2020-02-07T01:39:21.781Z] 17:39:21.779 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started | ||
|
|
||
| [debug] [2020-02-07T01:39:22.064Z] 17:39:22.064 [main] INFO com.firebase.server.forge.App$ - Listening at localhost:9000 | ||
|
|
||
| [info] ✔ database: Emulator started at http://localhost:9000 | ||
| [info] i database: For testing set FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000 | ||
| [info] i Running script: jest --no-cache --verbose --detectOpenHandles --forceExit | ||
| [debug] [2020-02-07T01:39:22.352Z] Running jest --no-cache --verbose --detectOpenHandles --forceExit with environment {"rvm_use_flag":"","npm_package_devDependencies_react_test_renderer":"^16.9.0","TERM_PROGRAM":"iTerm.app","rvm_bin_path":"/Users/jamesdaniels/.rvm/bin","NODE":"/Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin/node","INIT_CWD":"/Users/jamesdaniels/Code/reactfire/reactfire","NVM_CD_FLAGS":"-q","rvm_quiet_flag":"","npm_package_devDependencies_typescript":"^3.4.5","npm_package_homepage":"https://firebaseopensource.com/projects/firebase/reactfire/","npm_config_version_git_tag":"true","SHELL":"/bin/zsh","TERM":"xterm-256color","rvm_gemstone_url":"","npm_package_devDependencies_jest":"~24.9.0","TMPDIR":"/var/folders/tg/0v1n9rmd38lcl75lwmq0lhhm00bnbv/T/","rvm_docs_type":"","Apple_PubSub_Socket_Render":"/private/tmp/com.apple.launchd.v9uRuPAPLm/Render","npm_package_devDependencies__babel_preset_typescript":"^7.8.3","npm_config_init_license":"MIT","TERM_PROGRAM_VERSION":"3.3.7","npm_package_scripts_emulators":"firebase emulators:start --only firestore,database","TERM_SESSION_ID":"w0t0p0:1CF4B145-11F3-4C98-BDB9-9CBFCEBE17F9","rvm_hook":"","npm_package_private":"true","npm_config_registry":"https://registry.yarnpkg.com","ZSH":"/Users/jamesdaniels/.oh-my-zsh","npm_package_repository_url":"git+https://github.com/Firebase/reactfire.git","USER":"jamesdaniels","NVM_DIR":"/Users/jamesdaniels/.nvm","npm_package_devDependencies__testing_library_react":"^9.3.0","npm_package_description":"Firebase library for React","rvm_gemstone_package_file":"","npm_package_license":"MIT","npm_package_scripts_build_dev":"tsc --watch","rvm_path":"/Users/jamesdaniels/.rvm","npm_package_devDependencies_babel_jest":"^24.9.0","npm_package_devDependencies__babel_core":"^7.8.4","SSH_AUTH_SOCK":"/private/tmp/com.apple.launchd.K4d9zd3Th3/Listeners","__CF_USER_TEXT_ENCODING":"0x5D57B:0x0:0x0","npm_package_devDependencies__types_jest":"^24.9.0","rvm_proxy":"","npm_execpath":"/Users/jamesdaniels/.nvm/versions/node/v10.15.3/lib/node_modules/yarn/bin/yarn.js","PAGER":"less","rvm_ruby_file":"","LSCOLORS":"Gxfxcxdxbxegedabagacad","npm_package_devDependencies_firebase_tools":"^7.1.0","SK_SIGNING_PLUGIN":"gnubbyagent","rvm_prefix":"/Users/jamesdaniels","rvm_silent_flag":"","PATH":"/var/folders/tg/0v1n9rmd38lcl75lwmq0lhhm00bnbv/T/yarn--1581039556844-0.049035385658451114:/Users/jamesdaniels/Code/reactfire/reactfire/node_modules/.bin:/Users/jamesdaniels/.config/yarn/link/node_modules/.bin:/Users/jamesdaniels/Code/reactfire/node_modules/.bin:/Users/jamesdaniels/.yarn/bin:/Users/jamesdaniels/.nvm/versions/node/v10.15.3/libexec/lib/node_modules/npm/bin/node-gyp-bin:/Users/jamesdaniels/.nvm/versions/node/v10.15.3/lib/node_modules/npm/bin/node-gyp-bin:/Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin/node_modules/npm/bin/node-gyp-bin:/Users/jamesdaniels/Downloads/google-cloud-sdk/bin:/Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin:/usr/local/git/current/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/Users/jamesdaniels/.rvm/bin","rvm_ruby_make":"","npm_config_argv":"{\"remain\":[],\"cooked\":[\"run\",\"test\"],\"original\":[\"test\"]}","npm_package_devDependencies_rollup":"^1.26.3","_":"/Users/jamesdaniels/Code/reactfire/reactfire/node_modules/.bin/firebase","npm_package_devDependencies__babel_preset_es2015":"~7.0.0-beta.53","npm_package_devDependencies__testing_library_react_hooks":"^3.1.0","PWD":"/Users/jamesdaniels/Code/reactfire/reactfire","npm_package_devDependencies__rollup_plugin_node_resolve":"^7.0.0","npm_package_scripts_copy_package_json":"cp package.pub.json pub/reactfire/package.json","npm_package_bugs_url":"https://github.com/Firebase/reactfire/issues","npm_lifecycle_event":"test","npm_package_devDependencies_rollup_jest":"^0.0.2","LANG":"en_US.UTF-8","rvm_sdk":"","npm_package_repository_type":"git","npm_package_types":"index.d.ts","npm_package_name":"reactfire-dev","ITERM_PROFILE":"Default","npm_package_devDependencies__babel_preset_react":"^7.8.3","npm_package_devDependencies__babel_preset_env":"^7.8.4","npm_package_dependencies_rxjs":"^6.4.0","npm_package_scripts_build":"rm -rf pub && tsc && yarn copy-package-json && cp ../README.md pub/reactfire/README.md && cp ../LICENSE pub/reactfire/LICENSE && rollup -c","npm_config_version_commit_hooks":"true","XPC_FLAGS":"0x0","npm_config_bin_links":"true","npm_package_devDependencies__firebase_app_types":"^0.4.0","npm_package_scripts_test_dev":"jest --verbose --watch","npm_package_main":"index.js","XPC_SERVICE_NAME":"0","npm_package_scripts_watch":"yarn build && tsc --watch","npm_package_version":"2.0.0","rvm_version":"1.29.9 (latest)","COLORFGBG":"7;0","HOME":"/Users/jamesdaniels","SHLVL":"2","rvm_pretty_print_flag":"","rvm_script_name":"","npm_package_devDependencies_rollup_plugin_babel":"^4.3.3","rvm_ruby_mode":"","npm_package_scripts_test":"firebase emulators:exec --only firestore,database \"jest --no-cache --verbose --detectOpenHandles --forceExit\"","LC_TERMINAL_VERSION":"3.3.7","npm_config_save_prefix":"^","npm_config_strict_ssl":"true","npm_package_devDependencies_firebase_functions_test":"^0.1.6","npm_config_version_git_message":"v%s","npm_package_devDependencies__firebase_testing":"^0.11.4","ITERM_SESSION_ID":"w0t0p0:1CF4B145-11F3-4C98-BDB9-9CBFCEBE17F9","LOGNAME":"jamesdaniels","LESS":"-R","YARN_WRAP_OUTPUT":"false","rvm_alias_expanded":"","npm_lifecycle_script":"firebase emulators:exec --only firestore,database \"jest --no-cache --verbose --detectOpenHandles --forceExit\"","LC_CTYPE":"en_US.UTF-8","NVM_BIN":"/Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin","rvm_nightly_flag":"","npm_config_version_git_sign":"","npm_config_ignore_scripts":"","npm_config_user_agent":"yarn/1.21.1 npm/? node/v10.15.3 darwin x64","rvm_ruby_make_install":"","LC_TERMINAL":"iTerm2","rvm_niceness":"","rvm_ruby_bits":"","npm_package_dependencies_rxfire":"^3.6.6","rvm_bin_flag":"","npm_package_devDependencies__firebase_app":"^0.4.8","npm_config_init_version":"1.0.0","npm_config_ignore_optional":"","rvm_only_path_flag":"","COLORTERM":"truecolor","npm_node_execpath":"/Users/jamesdaniels/.nvm/versions/node/v10.15.3/bin/node","npm_package_devDependencies__testing_library_jest_dom":"^4.1.1","npm_config_version_tag_prefix":"v","FIREBASE_DATABASE_EMULATOR_HOST":"localhost:9000","FIRESTORE_EMULATOR_HOST":"localhost:8080","FIREBASE_FIRESTORE_EMULATOR_ADDRESS":"localhost:8080"} | ||
| [debug] [2020-02-07T01:39:26.361Z] Feb 06, 2020 5:39:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead | ||
| INFO: Detected HTTP/2 connection. | ||
|
|
||
| [debug] [2020-02-07T01:39:27.571Z] Feb 06, 2020 5:39:27 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead | ||
| INFO: Detected HTTP/2 connection. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module.exports = { | ||
| // "preset": "rollup-jest" | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import { Observable, Subject, Subscription, Subscriber } from 'rxjs'; | ||
| import { tap, share, first } from 'rxjs/operators'; | ||
|
|
||
| export class BehaviorReplaySubject<T> extends Subject<T> { | ||
| private _value: T | undefined; | ||
| private _hasValue = false; | ||
| private _timeoutHandler: NodeJS.Timeout | undefined; | ||
| private _innerSubscriber: any; | ||
| private _firstEmission: Promise<void>; | ||
| private _resolveFirstEmission: () => void; | ||
| private _error: any = undefined; | ||
| private _innerObservable: Observable<T>; | ||
|
|
||
| constructor(innerObservable: Observable<T>, private _timeoutWindow: number) { | ||
| super(); | ||
| this._firstEmission = new Promise<void>( | ||
| resolve => (this._resolveFirstEmission = resolve) | ||
| ); | ||
| this._innerObservable = innerObservable.pipe( | ||
| tap( | ||
| v => { | ||
| this._next(v); | ||
| }, | ||
| e => { | ||
| // save the error, so that we can raise on subscription or .value | ||
| // resolve the promise, so suspense tries again | ||
| this._error = e; | ||
| this._resolveFirstEmission(); | ||
| } | ||
| ), | ||
| share() | ||
| ); | ||
| // warm up the observable | ||
| this._innerObservable.pipe(first()).subscribe(); | ||
| } | ||
|
|
||
| get hasValue(): boolean { | ||
| // hasValue returns true if there's an error too | ||
| // so that after we resolve the promise & useObservable is called again | ||
| // we won't throw again | ||
| return this._hasValue || !!this._error; | ||
| } | ||
|
|
||
| get value(): T { | ||
| // throw on .value since the first().subscribe would otherwise | ||
| // absorb it, clear the error for retry | ||
| if (this._error) { | ||
| const error = this._error; | ||
| this._error = undefined; | ||
| if (!this._hasValue) { | ||
| // if we cheated around hasValue let's reset the suspense promise too | ||
| this._firstEmission = new Promise<void>( | ||
| resolve => (this._resolveFirstEmission = resolve) | ||
| ); | ||
| } | ||
| throw error; | ||
| } | ||
| return this._value; | ||
| } | ||
|
|
||
| get firstEmission(): Promise<void> { | ||
| return this._firstEmission; | ||
| } | ||
|
|
||
| private _next(value: T) { | ||
| this._hasValue = true; | ||
| this._value = value; | ||
| this._resolveFirstEmission(); | ||
| } | ||
|
|
||
| private _reset() { | ||
| // set a timeout for reseting the cache, subscriptions will cancel the timeout | ||
| // and reschedule again on unsubscribe | ||
| this._timeoutHandler = setTimeout(() => { | ||
| this._hasValue = false; | ||
| this._value = undefined; | ||
| this._error = undefined; | ||
| this._firstEmission = new Promise<void>( | ||
| resolve => (this._resolveFirstEmission = resolve) | ||
| ); | ||
| }, this._timeoutWindow); | ||
| } | ||
|
|
||
| _subscribe(subscriber: Subscriber<T>): Subscription { | ||
| // throw the error if there is one | ||
| if (this._error) { | ||
| // reset, so they can retry | ||
| const error = this._error; | ||
| this._error = undefined; | ||
| throw error; | ||
| } | ||
| if (this._timeoutHandler) { | ||
| clearTimeout(this._timeoutHandler); | ||
| } | ||
| this._innerSubscriber = this._innerObservable.subscribe(subscriber); | ||
| return this._innerSubscriber.add(this._reset); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.