Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReactNativeのAsyncStorageをNodeのReplから操作する

joe_re
December 14, 2017

 ReactNativeのAsyncStorageをNodeのReplから操作する

Introduce liblary named async-storage-repl.
AsyncStorage repl provides you to access your ReactNative Application AsyncStorage using your console node REPL.
It makes easy to development your app.
and it has more feture...

joe_re

December 14, 2017
Tweet

More Decks by joe_re

Other Decks in Technology

Transcript

  1. ReactNative

    AsyncStorage
    をNode

    Repl
    から操作する
    @joe_re

    View Slide

  2. Who am I?
    twitter: @joe_re
    github: @joe­re
    community: Nishinippori.rb, GraphQL Tokyo Organizer

    View Slide

  3. Note
    Gotanda.js
    で発表した以下の発表とかぶる部分が多いです。
    いらしていた方はすみません
    https://speakerdeck.com/joere/asyncstoragewonodefalsereplkaracao­
    zuo­surutamenitop­leveldeawaitsitairen­sheng­datuta

    View Slide

  4. What is AsyncStorage?
    ReactNative
    の標準で搭載されたkey­value
    ストレージ
    気軽にReactNative
    に永続化したいデータを持つときに便利
    ReactNative
    で使えるLocalStorage
    みたいなもの

    View Slide

  5. Example
    Persisting date:
    try {
    await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.');
    } catch (error) {
    // Error saving data
    }
    Fetching date:
    try {
    const value = await AsyncStorage.getItem('@MySuperStore:key');
    if (value !== null){
    // We have data!!
    console.log(value);
    }
    } catch (error) {
    // Error retrieving data
    }

    View Slide

  6. AsyncStorage
    をNode
    のREPL
    から操作したいという欲望
    AsyncStorage
    には外部から叩けるAPI
    は用意されていない
    開発中にデータ構造が変わったときにアプリケーションに
    データを修正するためのコードを書くのは面倒
    ちゃんとデータが保存されたかどうか確かめるのも面倒
    REPL
    からAsyncStorage
    のAPI
    を叩きたい
    (rails console
    みたいなイメージ)

    View Slide

  7. 作った
    https://github.com/joe­re/async­storage­repl

    View Slide

  8. DEMO

    View Slide

  9. 仕組み
    Node
    とReactNative
    との通信はWebsocket
    で行う
    REPL
    起動時に子プロセスとしてReactNative
    アプリケーションと通信するWSS
    を立ち上げる
    REPL
    とWSS
    はプロセス間通信を行う

    View Slide

  10. イメージ図

    View Slide

  11. ん?

    View Slide

  12. どうしてこうなった

    View Slide

  13. Node.js
    ではTop Level
    で非同期処理の
    結果を扱えない
    人類はES2017
    よりasync/await
    を獲得したが、
    await
    はasync function
    の中でしか使えない
    // ng
    function request {
    const response = await fetch( '/data.json' );
    const json = await response.json();
    const result = await hydrateSomehow(json);
    return result;
    }
    // ok
    function async request {
    const response = await fetch( '/data.json' );
    const json = await response.json();
    const result = await hydrateSomehow(json);
    return result;
    }

    View Slide

  14. REPL

    Promise
    オブジェクトを
    扱おうとすると..
    > let out = null;
    > promiseObj.then((res) => { out = res });
    > out // finally available here

    View Slide

  15. だるすぎワロた

    View Slide

  16. Top­level await is a footgun
    https://gist.github.com/Rich­
    Harris/0b6f317657f5167663b493c722647221
    Top­level
    のawait
    を許すと1
    つの依存を解決するだけでも、
    その先の関係のない処理まで止めざるを得ない
    await
    は直列を強要するので、ネットワークを介した処理
    (
    動的なmodule import
    など)
    の並列化ができない

    View Slide

  17. Example(borrow from Harris)
    // main.js
    import './foo.js';
    import './bar.js';
    // foo.js
    await delay( Math.random() * 1000 );
    console.log( 'foo happened' );
    // bar.js
    await delay( Math.random() * 1000 );
    console.log( 'bar happened' );

    View Slide

  18. 将来的にはTop­level await

    できるかも?
    https://github.com/tc39/ecmascript­asyncawait/issues/9

    View Slide

  19. 今回はこのような実装に
    _resolveMessageFromRN(fileName) {
    let json = {};
    let received = false;
    for (let i = 0; i < this.timeout; i++) {
    sleep.msleep(100);
    const fileContent = fs.readFileSync(fileName, 'utf8');
    if (fileContent) {
    json = JSON.parse(fileContent);
    delete this.que[Number(json.queId)];
    received = true;
    break;
    }
    sleep.msleep(900);
    }
    fs.unlinkSync(fileName);
    if (!received) {
    throw new Error("can't receive response from ReactNative Application");
    }
    if (json.error === 1) {
    throw new Error(json.message);
    }
    return json.result;
    }

    View Slide

  20. ここまで作った当時(2017/5
    月)
    の情報

    View Slide

  21. Chrome
    のDevTool
    には
    top­level await
    が入った

    View Slide

  22. それを受けてNode
    のRepl
    にも実装された
    v10
    系から入る予定。試してみたい人はlatest
    のソースコー
    ドからビルドすれば今でも使えるはずです
    https://github.com/nodejs/node/pull/15566

    View Slide

  23. というわけでファイル監視は
    そのうちやめられそう

    View Slide

  24. Flow Runtime
    の採用
    https://codemix.github.io/flow­runtime/
    compile
    でassertion
    をさし挟むことで、
    flowtype
    の型チェックを動的に実行できる
    全ての関数呼び出しでassertion
    を挟むのはパフォーマンス
    に影響するのでproduction
    ではoff
    にすべきだが、
    development
    やtest
    でon
    にしておくとより多くの型違反を
    検出できる
    REPL
    でこれを有効にしたら思ったよりこれぞ型チェックっ
    て感じになって感動した

    View Slide

  25. example
    > RNAsyncStorage.getItem(1)
    RuntimeTypeError: key must be a string
    Expected: string
    Actual Value: 1
    Actual Type: number
    at RNAsyncStorage.getItem (/Users/noguchimasato/src/async-storage-
    cli/src/node/RNAsyncStorage.js:25:24)
    at repl:1:16
    at sigintHandlersWrap (vm.js:92:15)
    at ContextifyScript.Script.runInThisContext (vm.js:42:12)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:433:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)

    View Slide

  26. Extensible AsyncStorage API
    基本はAsync Storage
    のAPI
    をそのまま提供しているけど、
    仕組み上API
    を組み合わせて新しいAPI
    を作ることや、
    拡張することも可能
    現在は dump()
    と load()
    のAPI
    を提供している
    もっと便利にしていきたいので是非アイディアをください

    View Slide

  27. ReactNative
    のお供にぜひ!

    View Slide

  28. ありがとうございました

    View Slide