@yume-chan/adb 2.6.2 → 3.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/esm/adb.d.ts +18 -15
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +18 -11
- package/esm/adb.js.map +1 -1
- package/esm/banner.d.ts +1 -1
- package/esm/banner.d.ts.map +1 -1
- package/esm/banner.js.map +1 -1
- package/esm/daemon/auth/authenticator.d.ts +28 -0
- package/esm/daemon/auth/authenticator.d.ts.map +1 -0
- package/esm/daemon/auth/authenticator.js +108 -0
- package/esm/daemon/auth/authenticator.js.map +1 -0
- package/esm/daemon/auth/index.d.ts +5 -0
- package/esm/daemon/auth/index.d.ts.map +1 -0
- package/esm/daemon/auth/index.js +5 -0
- package/esm/daemon/auth/index.js.map +1 -0
- package/esm/daemon/auth/packet-processor.d.ts +42 -0
- package/esm/daemon/auth/packet-processor.d.ts.map +1 -0
- package/esm/daemon/auth/packet-processor.js +129 -0
- package/esm/daemon/auth/packet-processor.js.map +1 -0
- package/esm/daemon/auth/public-key.d.ts +8 -0
- package/esm/daemon/auth/public-key.d.ts.map +1 -0
- package/esm/daemon/auth/public-key.js +74 -0
- package/esm/daemon/auth/public-key.js.map +1 -0
- package/esm/daemon/auth/type.d.ts +5 -0
- package/esm/daemon/auth/type.d.ts.map +1 -0
- package/esm/daemon/auth/type.js +2 -0
- package/esm/daemon/auth/type.js.map +1 -0
- package/esm/daemon/crypto.d.ts +6 -5
- package/esm/daemon/crypto.d.ts.map +1 -1
- package/esm/daemon/crypto.js +23 -72
- package/esm/daemon/crypto.js.map +1 -1
- package/esm/daemon/dispatcher.d.ts +3 -3
- package/esm/daemon/dispatcher.d.ts.map +1 -1
- package/esm/daemon/dispatcher.js +11 -4
- package/esm/daemon/dispatcher.js.map +1 -1
- package/esm/daemon/index.d.ts +1 -1
- package/esm/daemon/index.d.ts.map +1 -1
- package/esm/daemon/index.js +1 -1
- package/esm/daemon/index.js.map +1 -1
- package/esm/daemon/socket.d.ts +3 -3
- package/esm/daemon/socket.d.ts.map +1 -1
- package/esm/daemon/transport.d.ts +13 -65
- package/esm/daemon/transport.d.ts.map +1 -1
- package/esm/daemon/transport.js +18 -140
- package/esm/daemon/transport.js.map +1 -1
- package/esm/device-observer.d.ts +2 -3
- package/esm/device-observer.d.ts.map +1 -1
- package/esm/features-value.d.ts +40 -0
- package/esm/features-value.d.ts.map +1 -0
- package/esm/features-value.js +46 -0
- package/esm/features-value.js.map +1 -0
- package/esm/features.d.ts +4 -12
- package/esm/features.d.ts.map +1 -1
- package/esm/features.js +27 -13
- package/esm/features.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/server/client.d.ts +7 -7
- package/esm/server/client.d.ts.map +1 -1
- package/esm/server/client.js +69 -86
- package/esm/server/client.js.map +1 -1
- package/esm/server/commands/wireless.js +1 -1
- package/esm/server/commands/wireless.js.map +1 -1
- package/esm/server/{stream.d.ts → data-connection.d.ts} +5 -5
- package/esm/server/data-connection.d.ts.map +1 -0
- package/esm/server/{stream.js → data-connection.js} +4 -4
- package/esm/server/data-connection.js.map +1 -0
- package/esm/server/index.d.ts +1 -1
- package/esm/server/index.d.ts.map +1 -1
- package/esm/server/index.js +1 -1
- package/esm/server/index.js.map +1 -1
- package/esm/server/observer.d.ts.map +1 -1
- package/esm/server/observer.js +14 -13
- package/esm/server/observer.js.map +1 -1
- package/esm/server/transport.d.ts +4 -6
- package/esm/server/transport.d.ts.map +1 -1
- package/esm/server/transport.js +9 -24
- package/esm/server/transport.js.map +1 -1
- package/esm/service/framebuffer.d.ts.map +1 -0
- package/esm/service/framebuffer.js.map +1 -0
- package/esm/{commands → service}/index.d.ts +1 -2
- package/esm/service/index.d.ts.map +1 -0
- package/esm/{commands → service}/index.js +1 -2
- package/esm/service/index.js.map +1 -0
- package/esm/{commands → service}/power.d.ts +4 -2
- package/esm/service/power.d.ts.map +1 -0
- package/esm/{commands → service}/power.js +11 -5
- package/esm/service/power.js.map +1 -0
- package/esm/service/reverse/error.d.ts +14 -0
- package/esm/service/reverse/error.d.ts.map +1 -0
- package/esm/service/reverse/error.js +21 -0
- package/esm/service/reverse/error.js.map +1 -0
- package/esm/service/reverse/index.d.ts +3 -0
- package/esm/service/reverse/index.d.ts.map +1 -0
- package/esm/service/reverse/index.js +4 -0
- package/esm/service/reverse/index.js.map +1 -0
- package/esm/service/reverse/response.d.ts +2 -0
- package/esm/service/reverse/response.d.ts.map +1 -0
- package/esm/service/reverse/response.js +30 -0
- package/esm/service/reverse/response.js.map +1 -0
- package/esm/service/reverse/service.d.ts +59 -0
- package/esm/service/reverse/service.d.ts.map +1 -0
- package/esm/{commands/reverse.js → service/reverse/service.js} +16 -45
- package/esm/service/reverse/service.js.map +1 -0
- package/esm/{commands → service}/subprocess/index.d.ts +1 -0
- package/esm/service/subprocess/index.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/index.js +1 -0
- package/esm/service/subprocess/index.js.map +1 -0
- package/esm/service/subprocess/none/index.d.ts.map +1 -0
- package/esm/service/subprocess/none/index.js.map +1 -0
- package/esm/{commands → service}/subprocess/none/process.d.ts +2 -2
- package/esm/service/subprocess/none/process.d.ts.map +1 -0
- package/esm/service/subprocess/none/process.js.map +1 -0
- package/esm/{commands → service}/subprocess/none/pty.d.ts +4 -4
- package/esm/service/subprocess/none/pty.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/none/pty.js +1 -1
- package/esm/service/subprocess/none/pty.js.map +1 -0
- package/esm/service/subprocess/none/service.d.ts +10 -0
- package/esm/service/subprocess/none/service.d.ts.map +1 -0
- package/esm/service/subprocess/none/service.js +44 -0
- package/esm/service/subprocess/none/service.js.map +1 -0
- package/esm/service/subprocess/none/spawner.d.ts +15 -0
- package/esm/service/subprocess/none/spawner.d.ts.map +1 -0
- package/esm/service/subprocess/none/spawner.js +31 -0
- package/esm/service/subprocess/none/spawner.js.map +1 -0
- package/esm/{commands → service}/subprocess/pty.d.ts +1 -1
- package/esm/service/subprocess/pty.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/pty.js.map +1 -1
- package/esm/service/subprocess/service.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/service.js +1 -1
- package/esm/service/subprocess/service.js.map +1 -0
- package/esm/service/subprocess/shell/index.d.ts +5 -0
- package/esm/{commands/subprocess/none → service/subprocess/shell}/index.d.ts.map +1 -1
- package/esm/service/subprocess/shell/index.js +6 -0
- package/esm/{commands/subprocess/none → service/subprocess/shell}/index.js.map +1 -1
- package/esm/{commands → service}/subprocess/shell/process.d.ts +2 -2
- package/esm/service/subprocess/shell/process.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/shell/process.js +4 -6
- package/esm/service/subprocess/shell/process.js.map +1 -0
- package/esm/{commands → service}/subprocess/shell/pty.d.ts +4 -4
- package/esm/service/subprocess/shell/pty.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/shell/pty.js +11 -9
- package/esm/service/subprocess/shell/pty.js.map +1 -0
- package/esm/service/subprocess/shell/service.d.ts +34 -0
- package/esm/service/subprocess/shell/service.d.ts.map +1 -0
- package/esm/service/subprocess/shell/service.js +52 -0
- package/esm/service/subprocess/shell/service.js.map +1 -0
- package/esm/service/subprocess/shell/shared.d.ts +2 -0
- package/esm/service/subprocess/shell/shared.d.ts.map +1 -0
- package/esm/{commands → service}/subprocess/shell/shared.js +2 -0
- package/esm/service/subprocess/shell/shared.js.map +1 -0
- package/esm/{commands → service}/subprocess/shell/spawner.d.ts +3 -7
- package/esm/service/subprocess/shell/spawner.d.ts.map +1 -0
- package/esm/service/subprocess/shell/spawner.js +45 -0
- package/esm/service/subprocess/shell/spawner.js.map +1 -0
- package/esm/service/subprocess/types.d.ts +14 -0
- package/esm/service/subprocess/types.d.ts.map +1 -0
- package/esm/service/subprocess/types.js +2 -0
- package/esm/service/subprocess/types.js.map +1 -0
- package/esm/service/subprocess/utils.d.ts +39 -0
- package/esm/service/subprocess/utils.d.ts.map +1 -0
- package/esm/service/subprocess/utils.js +142 -0
- package/esm/service/subprocess/utils.js.map +1 -0
- package/esm/service/sync/android.d.ts +34 -0
- package/esm/service/sync/android.d.ts.map +1 -0
- package/esm/service/sync/android.js +34 -0
- package/esm/service/sync/android.js.map +1 -0
- package/esm/service/sync/compression/compression.d.ts +17 -0
- package/esm/service/sync/compression/compression.d.ts.map +1 -0
- package/esm/service/sync/compression/compression.js +92 -0
- package/esm/service/sync/compression/compression.js.map +1 -0
- package/esm/service/sync/compression/format-ns.d.ts +5 -0
- package/esm/service/sync/compression/format-ns.d.ts.map +1 -0
- package/esm/service/sync/compression/format-ns.js +5 -0
- package/esm/service/sync/compression/format-ns.js.map +1 -0
- package/esm/service/sync/compression/format.d.ts +4 -0
- package/esm/service/sync/compression/format.d.ts.map +1 -0
- package/esm/service/sync/compression/format.js +3 -0
- package/esm/service/sync/compression/format.js.map +1 -0
- package/esm/service/sync/compression/index.d.ts +2 -0
- package/esm/service/sync/compression/index.d.ts.map +1 -0
- package/esm/service/sync/compression/index.js +2 -0
- package/esm/service/sync/compression/index.js.map +1 -0
- package/esm/service/sync/id/common.d.ts +17 -0
- package/esm/service/sync/id/common.d.ts.map +1 -0
- package/esm/service/sync/id/common.js +29 -0
- package/esm/service/sync/id/common.js.map +1 -0
- package/esm/service/sync/id/index.d.ts +4 -0
- package/esm/service/sync/id/index.d.ts.map +1 -0
- package/esm/service/sync/id/index.js +6 -0
- package/esm/service/sync/id/index.js.map +1 -0
- package/esm/service/sync/id/request.d.ts +7 -0
- package/esm/service/sync/id/request.d.ts.map +1 -0
- package/esm/service/sync/id/request.js +9 -0
- package/esm/service/sync/id/request.js.map +1 -0
- package/esm/service/sync/id/response.d.ts +6 -0
- package/esm/service/sync/id/response.d.ts.map +1 -0
- package/esm/service/sync/id/response.js +8 -0
- package/esm/service/sync/id/response.js.map +1 -0
- package/esm/service/sync/index-ns.d.ts +7 -0
- package/esm/service/sync/index-ns.d.ts.map +1 -0
- package/esm/service/sync/index-ns.js +7 -0
- package/esm/service/sync/index-ns.js.map +1 -0
- package/esm/service/sync/index.d.ts +3 -0
- package/esm/service/sync/index.d.ts.map +1 -0
- package/esm/service/sync/index.js +3 -0
- package/esm/service/sync/index.js.map +1 -0
- package/esm/service/sync/request/index.d.ts +5 -0
- package/esm/service/sync/request/index.d.ts.map +1 -0
- package/esm/service/sync/request/index.js +5 -0
- package/esm/service/sync/request/index.js.map +1 -0
- package/esm/{commands/sync → service/sync/request}/list.d.ts +21 -19
- package/esm/service/sync/request/list.d.ts.map +1 -0
- package/esm/service/sync/request/list.js +77 -0
- package/esm/service/sync/request/list.js.map +1 -0
- package/esm/service/sync/request/pull.d.ts +12 -0
- package/esm/service/sync/request/pull.d.ts.map +1 -0
- package/esm/service/sync/request/pull.js +28 -0
- package/esm/service/sync/request/pull.js.map +1 -0
- package/esm/service/sync/request/push.d.ts +54 -0
- package/esm/service/sync/request/push.d.ts.map +1 -0
- package/esm/service/sync/request/push.js +95 -0
- package/esm/service/sync/request/push.js.map +1 -0
- package/esm/{commands/sync → service/sync/request}/stat.d.ts +40 -50
- package/esm/service/sync/request/stat.d.ts.map +1 -0
- package/esm/service/sync/request/stat.js +89 -0
- package/esm/service/sync/request/stat.js.map +1 -0
- package/esm/service/sync/service.d.ts +123 -0
- package/esm/service/sync/service.d.ts.map +1 -0
- package/esm/service/sync/service.js +170 -0
- package/esm/service/sync/service.js.map +1 -0
- package/esm/service/sync/socket-pool.d.ts +11 -0
- package/esm/service/sync/socket-pool.d.ts.map +1 -0
- package/esm/service/sync/socket-pool.js +80 -0
- package/esm/service/sync/socket-pool.js.map +1 -0
- package/esm/service/sync/socket.d.ts +40 -0
- package/esm/service/sync/socket.d.ts.map +1 -0
- package/esm/service/sync/socket.js +153 -0
- package/esm/service/sync/socket.js.map +1 -0
- package/esm/{commands → service}/tcpip.d.ts +4 -2
- package/esm/service/tcpip.d.ts.map +1 -0
- package/esm/{commands → service}/tcpip.js +10 -7
- package/esm/service/tcpip.js.map +1 -0
- package/esm/utils/array-buffer.d.ts.map +1 -1
- package/esm/utils/array-buffer.js +2 -3
- package/esm/utils/array-buffer.js.map +1 -1
- package/esm/utils/base64.d.ts.map +1 -1
- package/esm/utils/base64.js +22 -10
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/index.d.ts +1 -0
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +1 -0
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/md5.d.ts +8 -0
- package/esm/utils/md5.d.ts.map +1 -0
- package/esm/utils/md5.js +149 -0
- package/esm/utils/md5.js.map +1 -0
- package/package.json +9 -9
- package/src/adb.ts +44 -35
- package/src/banner.ts +2 -1
- package/src/daemon/auth/authenticator.ts +186 -0
- package/src/daemon/auth/index.ts +4 -0
- package/src/daemon/auth/packet-processor.ts +212 -0
- package/src/daemon/auth/public-key.ts +112 -0
- package/src/daemon/auth/type.ts +5 -0
- package/src/daemon/crypto.ts +36 -101
- package/src/daemon/dispatcher.ts +15 -8
- package/src/daemon/index.ts +1 -1
- package/src/daemon/socket.ts +3 -3
- package/src/daemon/transport.ts +35 -253
- package/src/device-observer.ts +3 -3
- package/src/features-value.ts +47 -0
- package/src/features.ts +31 -14
- package/src/index.ts +1 -1
- package/src/server/client.ts +94 -93
- package/src/server/commands/wireless.ts +1 -1
- package/src/server/{stream.ts → data-connection.ts} +4 -4
- package/src/server/index.ts +1 -1
- package/src/server/observer.ts +21 -19
- package/src/server/transport.ts +13 -34
- package/src/{commands → service}/index.ts +1 -2
- package/src/{commands → service}/power.ts +14 -5
- package/src/service/reverse/error.ts +35 -0
- package/src/service/reverse/index.ts +3 -0
- package/src/service/reverse/response.ts +38 -0
- package/src/{commands/reverse.ts → service/reverse/service.ts} +32 -72
- package/src/{commands → service}/subprocess/index.ts +1 -0
- package/src/{commands → service}/subprocess/none/process.ts +3 -3
- package/src/{commands → service}/subprocess/none/pty.ts +5 -5
- package/src/service/subprocess/none/service.ts +57 -0
- package/src/service/subprocess/none/spawner.ts +81 -0
- package/src/{commands → service}/subprocess/pty.ts +1 -1
- package/src/{commands → service}/subprocess/service.ts +1 -1
- package/src/{commands → service}/subprocess/shell/index.ts +1 -1
- package/src/{commands → service}/subprocess/shell/process.ts +6 -7
- package/src/{commands → service}/subprocess/shell/pty.ts +15 -13
- package/src/service/subprocess/shell/service.ts +75 -0
- package/src/{commands → service}/subprocess/shell/shared.ts +5 -0
- package/src/service/subprocess/shell/spawner.ts +109 -0
- package/src/service/subprocess/types.ts +19 -0
- package/src/service/subprocess/utils.ts +166 -0
- package/src/service/sync/android.ts +43 -0
- package/src/service/sync/compression/compression.ts +126 -0
- package/src/service/sync/compression/format-ns.ts +4 -0
- package/src/service/sync/compression/format.ts +5 -0
- package/src/service/sync/compression/index.ts +1 -0
- package/src/service/sync/id/common.ts +33 -0
- package/src/service/sync/id/index.ts +7 -0
- package/src/service/sync/id/request.ts +12 -0
- package/src/service/sync/id/response.ts +11 -0
- package/src/service/sync/index-ns.ts +6 -0
- package/src/service/sync/index.ts +2 -0
- package/src/service/sync/request/index.ts +4 -0
- package/src/service/sync/request/list.ts +110 -0
- package/src/service/sync/request/pull.ts +49 -0
- package/src/service/sync/request/push.ts +184 -0
- package/src/service/sync/request/stat.ts +127 -0
- package/src/service/sync/service.ts +255 -0
- package/src/service/sync/socket-pool.ts +97 -0
- package/src/service/sync/socket.ts +201 -0
- package/src/{commands → service}/tcpip.ts +13 -7
- package/src/utils/array-buffer.ts +2 -3
- package/src/utils/base64.ts +24 -10
- package/src/utils/index.ts +1 -0
- package/src/utils/md5.ts +185 -0
- package/yume-chan-adb-3.0.0-beta.0.tgz +0 -0
- package/CHANGELOG.md +0 -257
- package/esm/commands/base.d.ts +0 -8
- package/esm/commands/base.d.ts.map +0 -1
- package/esm/commands/base.js +0 -12
- package/esm/commands/base.js.map +0 -1
- package/esm/commands/framebuffer.d.ts.map +0 -1
- package/esm/commands/framebuffer.js.map +0 -1
- package/esm/commands/index.d.ts.map +0 -1
- package/esm/commands/index.js.map +0 -1
- package/esm/commands/power.d.ts.map +0 -1
- package/esm/commands/power.js.map +0 -1
- package/esm/commands/reverse.d.ts +0 -48
- package/esm/commands/reverse.d.ts.map +0 -1
- package/esm/commands/reverse.js.map +0 -1
- package/esm/commands/subprocess/index.d.ts.map +0 -1
- package/esm/commands/subprocess/index.js.map +0 -1
- package/esm/commands/subprocess/none/process.d.ts.map +0 -1
- package/esm/commands/subprocess/none/process.js.map +0 -1
- package/esm/commands/subprocess/none/pty.d.ts.map +0 -1
- package/esm/commands/subprocess/none/pty.js.map +0 -1
- package/esm/commands/subprocess/none/service.d.ts +0 -10
- package/esm/commands/subprocess/none/service.d.ts.map +0 -1
- package/esm/commands/subprocess/none/service.js +0 -34
- package/esm/commands/subprocess/none/service.js.map +0 -1
- package/esm/commands/subprocess/none/spawner.d.ts +0 -19
- package/esm/commands/subprocess/none/spawner.d.ts.map +0 -1
- package/esm/commands/subprocess/none/spawner.js +0 -26
- package/esm/commands/subprocess/none/spawner.js.map +0 -1
- package/esm/commands/subprocess/pty.d.ts.map +0 -1
- package/esm/commands/subprocess/service.d.ts.map +0 -1
- package/esm/commands/subprocess/service.js.map +0 -1
- package/esm/commands/subprocess/shell/index.d.ts +0 -6
- package/esm/commands/subprocess/shell/index.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/index.js +0 -6
- package/esm/commands/subprocess/shell/index.js.map +0 -1
- package/esm/commands/subprocess/shell/process.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/process.js.map +0 -1
- package/esm/commands/subprocess/shell/pty.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/pty.js.map +0 -1
- package/esm/commands/subprocess/shell/service.d.ts +0 -14
- package/esm/commands/subprocess/shell/service.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/service.js +0 -41
- package/esm/commands/subprocess/shell/service.js.map +0 -1
- package/esm/commands/subprocess/shell/shared.d.ts +0 -19
- package/esm/commands/subprocess/shell/shared.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/shared.js.map +0 -1
- package/esm/commands/subprocess/shell/spawner.d.ts.map +0 -1
- package/esm/commands/subprocess/shell/spawner.js +0 -38
- package/esm/commands/subprocess/shell/spawner.js.map +0 -1
- package/esm/commands/subprocess/utils.d.ts +0 -3
- package/esm/commands/subprocess/utils.d.ts.map +0 -1
- package/esm/commands/subprocess/utils.js +0 -56
- package/esm/commands/subprocess/utils.js.map +0 -1
- package/esm/commands/sync/index.d.ts +0 -9
- package/esm/commands/sync/index.d.ts.map +0 -1
- package/esm/commands/sync/index.js +0 -9
- package/esm/commands/sync/index.js.map +0 -1
- package/esm/commands/sync/list.d.ts.map +0 -1
- package/esm/commands/sync/list.js +0 -64
- package/esm/commands/sync/list.js.map +0 -1
- package/esm/commands/sync/pull.d.ts +0 -12
- package/esm/commands/sync/pull.d.ts.map +0 -1
- package/esm/commands/sync/pull.js +0 -33
- package/esm/commands/sync/pull.js.map +0 -1
- package/esm/commands/sync/push.d.ts +0 -61
- package/esm/commands/sync/push.d.ts.map +0 -1
- package/esm/commands/sync/push.js +0 -83
- package/esm/commands/sync/push.js.map +0 -1
- package/esm/commands/sync/request.d.ts +0 -24
- package/esm/commands/sync/request.d.ts.map +0 -1
- package/esm/commands/sync/request.js +0 -32
- package/esm/commands/sync/request.js.map +0 -1
- package/esm/commands/sync/response.d.ts +0 -28
- package/esm/commands/sync/response.d.ts.map +0 -1
- package/esm/commands/sync/response.js +0 -81
- package/esm/commands/sync/response.js.map +0 -1
- package/esm/commands/sync/socket.d.ts +0 -22
- package/esm/commands/sync/socket.d.ts.map +0 -1
- package/esm/commands/sync/socket.js +0 -78
- package/esm/commands/sync/socket.js.map +0 -1
- package/esm/commands/sync/stat.d.ts.map +0 -1
- package/esm/commands/sync/stat.js +0 -121
- package/esm/commands/sync/stat.js.map +0 -1
- package/esm/commands/sync/sync.d.ts +0 -82
- package/esm/commands/sync/sync.d.ts.map +0 -1
- package/esm/commands/sync/sync.js +0 -138
- package/esm/commands/sync/sync.js.map +0 -1
- package/esm/commands/tcpip.d.ts.map +0 -1
- package/esm/commands/tcpip.js.map +0 -1
- package/esm/daemon/auth.d.ts +0 -54
- package/esm/daemon/auth.d.ts.map +0 -1
- package/esm/daemon/auth.js +0 -104
- package/esm/daemon/auth.js.map +0 -1
- package/esm/server/stream.d.ts.map +0 -1
- package/esm/server/stream.js.map +0 -1
- package/src/commands/base.ts +0 -15
- package/src/commands/subprocess/none/service.ts +0 -45
- package/src/commands/subprocess/none/spawner.ts +0 -68
- package/src/commands/subprocess/shell/service.ts +0 -58
- package/src/commands/subprocess/shell/spawner.ts +0 -90
- package/src/commands/subprocess/utils.ts +0 -61
- package/src/commands/sync/index.ts +0 -8
- package/src/commands/sync/list.ts +0 -99
- package/src/commands/sync/pull.ts +0 -55
- package/src/commands/sync/push.ts +0 -172
- package/src/commands/sync/request.ts +0 -53
- package/src/commands/sync/response.ts +0 -105
- package/src/commands/sync/socket.ts +0 -109
- package/src/commands/sync/stat.ts +0 -177
- package/src/commands/sync/sync.ts +0 -175
- package/src/daemon/auth.ts +0 -203
- package/tsconfig.build.tsbuildinfo +0 -1
- /package/esm/{commands → service}/framebuffer.d.ts +0 -0
- /package/esm/{commands → service}/framebuffer.js +0 -0
- /package/esm/{commands → service}/subprocess/none/index.d.ts +0 -0
- /package/esm/{commands → service}/subprocess/none/index.js +0 -0
- /package/esm/{commands → service}/subprocess/none/process.js +0 -0
- /package/esm/{commands → service}/subprocess/pty.js +0 -0
- /package/esm/{commands → service}/subprocess/service.d.ts +0 -0
- /package/src/{commands → service}/framebuffer.ts +0 -0
- /package/src/{commands → service}/subprocess/none/index.ts +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { AdbFeature } from "../../features.js";
|
|
2
|
+
import { escapeArg } from "../subprocess/index.js";
|
|
3
|
+
import { Compression } from "./compression/index.js";
|
|
4
|
+
import { OpenDir, Receive, Send, Stat } from "./request/index.js";
|
|
5
|
+
import { SocketPool } from "./socket-pool.js";
|
|
6
|
+
import { Error as AdbSyncError } from "./socket.js";
|
|
7
|
+
/**
|
|
8
|
+
* A simplified `dirname` function that only handles absolute unix paths.
|
|
9
|
+
* @param path an absolute unix path
|
|
10
|
+
* @returns the directory name of the input path
|
|
11
|
+
*/
|
|
12
|
+
export function dirname(path) {
|
|
13
|
+
const end = path.lastIndexOf("/");
|
|
14
|
+
if (end === -1) {
|
|
15
|
+
throw new Error(`Invalid absolute unix path: ${path}`);
|
|
16
|
+
}
|
|
17
|
+
if (end === 0) {
|
|
18
|
+
return "/";
|
|
19
|
+
}
|
|
20
|
+
return path.substring(0, end);
|
|
21
|
+
}
|
|
22
|
+
export class Service {
|
|
23
|
+
_adb;
|
|
24
|
+
#socketPool;
|
|
25
|
+
#supportsStat2;
|
|
26
|
+
#supportsLs2;
|
|
27
|
+
#fixedPushMkdir;
|
|
28
|
+
#supportsSendReceive2;
|
|
29
|
+
#needPushMkdirWorkaround;
|
|
30
|
+
get supportsStat2() {
|
|
31
|
+
return this.#supportsStat2;
|
|
32
|
+
}
|
|
33
|
+
get supportsLs2() {
|
|
34
|
+
return this.#supportsLs2;
|
|
35
|
+
}
|
|
36
|
+
get fixedPushMkdir() {
|
|
37
|
+
return this.#fixedPushMkdir;
|
|
38
|
+
}
|
|
39
|
+
get supportsSendReceive2() {
|
|
40
|
+
return this.#supportsSendReceive2;
|
|
41
|
+
}
|
|
42
|
+
get needPushMkdirWorkaround() {
|
|
43
|
+
return this.#needPushMkdirWorkaround;
|
|
44
|
+
}
|
|
45
|
+
constructor(adb, options) {
|
|
46
|
+
this._adb = adb;
|
|
47
|
+
this.#socketPool = new SocketPool(adb, options?.maxPoolSize, options?.idleTimeout);
|
|
48
|
+
// Dispose the socket pool when the abort signal is triggered
|
|
49
|
+
options?.signal?.addEventListener("abort", () => {
|
|
50
|
+
void this.#socketPool.dispose();
|
|
51
|
+
});
|
|
52
|
+
this.#supportsStat2 = adb.canUseFeature(AdbFeature.Stat2);
|
|
53
|
+
this.#supportsLs2 = adb.canUseFeature(AdbFeature.Ls2);
|
|
54
|
+
this.#fixedPushMkdir = adb.canUseFeature(AdbFeature.FixedPushMkdir);
|
|
55
|
+
this.#supportsSendReceive2 = adb.canUseFeature(AdbFeature.SendReceive2);
|
|
56
|
+
// https://android.googlesource.com/platform/packages/modules/adb/+/91768a57b7138166e0a3d11f79cd55909dda7014/client/file_sync_client.cpp#1361
|
|
57
|
+
this.#needPushMkdirWorkaround =
|
|
58
|
+
this._adb.canUseFeature(AdbFeature.Shell2) && !this.fixedPushMkdir;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Acquires a socket from the pool for direct use.
|
|
62
|
+
*
|
|
63
|
+
* The socket must be returned to the pool using {@link releaseSocket} after use.
|
|
64
|
+
*
|
|
65
|
+
* @returns A socket from the pool
|
|
66
|
+
*/
|
|
67
|
+
async acquireSocket() {
|
|
68
|
+
return await this.#socketPool.acquire();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns a socket to the pool after use.
|
|
72
|
+
*
|
|
73
|
+
* @param socket The socket to return to the pool
|
|
74
|
+
* @param discard Whether to discard the socket instead of returning it to the pool
|
|
75
|
+
*/
|
|
76
|
+
async releaseSocket(socket, discard = false) {
|
|
77
|
+
await this.#socketPool.release(socket, discard);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Gets information of a file or folder.
|
|
81
|
+
*
|
|
82
|
+
* If `path` points to a symbolic link, the returned information is about the link itself (with `type` being `LinuxFileType.Link`).
|
|
83
|
+
*/
|
|
84
|
+
lstat(path) {
|
|
85
|
+
return Stat.lstat(this.#socketPool, path, {
|
|
86
|
+
version: this.#supportsStat2 ? 2 : 1,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gets the information of a file or folder.
|
|
91
|
+
*
|
|
92
|
+
* If `path` points to a symbolic link, it will be resolved and the returned information is about the target (with `type` being `LinuxFileType.File` or `LinuxFileType.Directory`).
|
|
93
|
+
*/
|
|
94
|
+
stat(path) {
|
|
95
|
+
if (!this.#supportsStat2) {
|
|
96
|
+
throw new Error("Not supported");
|
|
97
|
+
}
|
|
98
|
+
return Stat.stat(this.#socketPool, path);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Checks if `path` is a directory, or a symbolic link to a directory.
|
|
102
|
+
*
|
|
103
|
+
* This uses `lstat` internally, thus works on all Android versions.
|
|
104
|
+
*/
|
|
105
|
+
async isDirectory(path) {
|
|
106
|
+
try {
|
|
107
|
+
await this.lstat(path + "/");
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
if (e instanceof AdbSyncError) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
throw e;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
opendir(path) {
|
|
120
|
+
return OpenDir.opendir(this.#socketPool, path, {
|
|
121
|
+
version: this.supportsLs2 ? 2 : 1,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async readdir(path) {
|
|
125
|
+
// TODO: Convert to `Array.fromAsync`
|
|
126
|
+
const results = [];
|
|
127
|
+
for await (const entry of this.opendir(path)) {
|
|
128
|
+
results.push(entry);
|
|
129
|
+
}
|
|
130
|
+
return results;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Reads the content of a file on device.
|
|
134
|
+
*
|
|
135
|
+
* @param filename The full path of the file on device to read.
|
|
136
|
+
* @returns A `ReadableStream` that contains the file content.
|
|
137
|
+
*/
|
|
138
|
+
read(filename) {
|
|
139
|
+
return Receive.stream(this.#socketPool, filename);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Writes a file on device. If the file name already exists, it will be overwritten.
|
|
143
|
+
*
|
|
144
|
+
* @param options The content and options of the file to write.
|
|
145
|
+
*/
|
|
146
|
+
async write(options) {
|
|
147
|
+
if (this.needPushMkdirWorkaround) {
|
|
148
|
+
// It may fail if `filename` already exists.
|
|
149
|
+
// Ignore the result.
|
|
150
|
+
// TODO: sync: test push mkdir workaround (need an Android 8 device)
|
|
151
|
+
await this._adb.subprocess.noneProtocol
|
|
152
|
+
.spawn(["mkdir", "-p", escapeArg(dirname(options.filename))])
|
|
153
|
+
.wait();
|
|
154
|
+
}
|
|
155
|
+
if (this.supportsSendReceive2) {
|
|
156
|
+
if (options.compression === undefined) {
|
|
157
|
+
options.compression = Compression.chooseFormat(this._adb, Compression.Mode.Compress);
|
|
158
|
+
}
|
|
159
|
+
else if (!Compression.canUseFormat(this._adb, options.compression, Compression.Mode.Compress)) {
|
|
160
|
+
throw new Error(`Compression type ${options.compression} is not supported`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
await Send.send({
|
|
164
|
+
version: this.supportsSendReceive2 ? 2 : 1,
|
|
165
|
+
pool: this.#socketPool,
|
|
166
|
+
...options,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/service/sync/service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,KAAK,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAuBpD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,GAAG,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAsBD,MAAM,OAAO,OAAO;IACN,IAAI,CAAM;IACX,WAAW,CAAa;IAExB,cAAc,CAAU;IACxB,YAAY,CAAU;IACtB,eAAe,CAAU;IACzB,qBAAqB,CAAU;IAC/B,wBAAwB,CAAU;IAE3C,IAAI,aAAa;QACb,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAED,IAAI,WAAW;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAED,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;IAED,IAAI,oBAAoB;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACtC,CAAC;IAED,IAAI,uBAAuB;QACvB,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACzC,CAAC;IAED,YAAY,GAAQ,EAAE,OAAwB;QAC1C,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAC7B,GAAG,EACH,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,WAAW,CACvB,CAAC;QAEF,6DAA6D;QAC7D,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YAC5C,KAAK,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QACpE,IAAI,CAAC,qBAAqB,GAAG,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACxE,6IAA6I;QAC7I,IAAI,CAAC,wBAAwB;YACzB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;IAC3E,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa;QACf,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,OAAO,GAAG,KAAK;QAC/C,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE;YACtC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvC,CAAC,CAAC;IACP,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,IAAY;QACb,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY;QAC1B,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,CAAC;YACZ,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,CAAC,IAAY;QAChB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE;YAC3C,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACpC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY;QACtB,qCAAqC;QACrC,MAAM,OAAO,GAAoB,EAAE,CAAC;QACpC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,QAAgB;QACjB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,OAAqB;QAC7B,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,4CAA4C;YAC5C,qBAAqB;YACrB,oEAAoE;YACpE,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY;iBAClC,KAAK,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;iBAC5D,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBACpC,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC,YAAY,CAC1C,IAAI,CAAC,IAAI,EACT,WAAW,CAAC,IAAI,CAAC,QAAQ,CAC5B,CAAC;YACN,CAAC;iBAAM,IACH,CAAC,WAAW,CAAC,YAAY,CACrB,IAAI,CAAC,IAAI,EACT,OAAO,CAAC,WAAW,EACnB,WAAW,CAAC,IAAI,CAAC,QAAQ,CAC5B,EACH,CAAC;gBACC,MAAM,IAAI,KAAK,CACX,oBAAoB,OAAO,CAAC,WAAW,mBAAmB,CAC7D,CAAC;YACN,CAAC;QACL,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,CAAC;YACZ,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,GAAG,OAAO;SACb,CAAC,CAAC;IACP,CAAC;CACJ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Adb } from "../../adb.js";
|
|
2
|
+
import { Socket } from "./socket.js";
|
|
3
|
+
export declare class SocketPool {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(adb: Adb, maxSize?: number, idleTimeout?: number);
|
|
6
|
+
acquire(): Promise<Socket>;
|
|
7
|
+
withSocket<T>(fn: (socket: Socket) => Promise<T>): Promise<T>;
|
|
8
|
+
release(socket: Socket, discard?: boolean): Promise<void>;
|
|
9
|
+
dispose(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=socket-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-pool.d.ts","sourceRoot":"","sources":["../../../src/service/sync/socket-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAyB,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5D,qBAAa,UAAU;;gBAQP,GAAG,EAAE,GAAG,EAAE,OAAO,SAAI,EAAE,WAAW,SAAQ;IAMhD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAwB1B,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAY7D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAiBjC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Error as AdbSyncError, Socket } from "./socket.js";
|
|
2
|
+
export class SocketPool {
|
|
3
|
+
#adb;
|
|
4
|
+
#maxSize;
|
|
5
|
+
#idleTimeout;
|
|
6
|
+
#availableSockets = [];
|
|
7
|
+
#inUseSockets = new Set();
|
|
8
|
+
#closed = false;
|
|
9
|
+
constructor(adb, maxSize = 4, idleTimeout = 60000) {
|
|
10
|
+
this.#adb = adb;
|
|
11
|
+
this.#maxSize = maxSize;
|
|
12
|
+
this.#idleTimeout = idleTimeout;
|
|
13
|
+
}
|
|
14
|
+
async acquire() {
|
|
15
|
+
if (this.#closed) {
|
|
16
|
+
throw new Error("SocketPool is closed");
|
|
17
|
+
}
|
|
18
|
+
// Try to reuse an available socket
|
|
19
|
+
if (this.#availableSockets.length > 0) {
|
|
20
|
+
const socket = this.#availableSockets.pop();
|
|
21
|
+
// Clear the idle timeout
|
|
22
|
+
socket.clearIdleTimer();
|
|
23
|
+
this.#inUseSockets.add(socket);
|
|
24
|
+
return socket;
|
|
25
|
+
}
|
|
26
|
+
// Create a new socket
|
|
27
|
+
const adbSocket = await this.#adb.createSocket("sync:");
|
|
28
|
+
if (this.#closed) {
|
|
29
|
+
await adbSocket.close();
|
|
30
|
+
throw new Error("SocketPool is closed");
|
|
31
|
+
}
|
|
32
|
+
const socket = new Socket(adbSocket, this.#adb.maxPayloadSize);
|
|
33
|
+
this.#inUseSockets.add(socket);
|
|
34
|
+
return socket;
|
|
35
|
+
}
|
|
36
|
+
async withSocket(fn) {
|
|
37
|
+
const socket = await this.acquire();
|
|
38
|
+
try {
|
|
39
|
+
const result = await fn(socket);
|
|
40
|
+
await this.release(socket);
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
await this.release(socket, !(e instanceof AdbSyncError));
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async release(socket, discard = false) {
|
|
49
|
+
this.#inUseSockets.delete(socket);
|
|
50
|
+
// If discarding or we already have enough sockets in the pool, close this socket
|
|
51
|
+
if (discard || this.#availableSockets.length >= this.#maxSize) {
|
|
52
|
+
await socket.close();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Otherwise, return it to the pool and start idle timeout
|
|
56
|
+
socket.startIdleTimer(this.#idleTimeout, () => {
|
|
57
|
+
this.#closeIdleSocket(socket);
|
|
58
|
+
});
|
|
59
|
+
this.#availableSockets.push(socket);
|
|
60
|
+
}
|
|
61
|
+
#closeIdleSocket(socket) {
|
|
62
|
+
// Remove from available sockets
|
|
63
|
+
const index = this.#availableSockets.indexOf(socket);
|
|
64
|
+
if (index !== -1) {
|
|
65
|
+
this.#availableSockets.splice(index, 1);
|
|
66
|
+
void socket.close();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async dispose() {
|
|
70
|
+
this.#closed = true;
|
|
71
|
+
// Close all available sockets
|
|
72
|
+
const closePromises = this.#availableSockets.map((socket) => socket.close());
|
|
73
|
+
this.#availableSockets.length = 0;
|
|
74
|
+
// Force close all in-use sockets immediately
|
|
75
|
+
const inUseClosePromises = Array.from(this.#inUseSockets).map((socket) => socket.close());
|
|
76
|
+
this.#inUseSockets.clear();
|
|
77
|
+
await Promise.all([...closePromises, ...inUseClosePromises]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=socket-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-pool.js","sourceRoot":"","sources":["../../../src/service/sync/socket-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AsyncExactReadable, StructDeserializer } from "@yume-chan/struct";
|
|
2
|
+
import type { Adb } from "../../adb.js";
|
|
3
|
+
declare class AdbSyncError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export { AdbSyncError as Error };
|
|
6
|
+
export declare class Socket implements AsyncExactReadable {
|
|
7
|
+
#private;
|
|
8
|
+
static readonly NumberRequest: import("@yume-chan/struct").Struct<{
|
|
9
|
+
id: import("@yume-chan/struct").NumberField<number>;
|
|
10
|
+
arg: import("@yume-chan/struct").NumberField<number>;
|
|
11
|
+
}, undefined, import("@yume-chan/struct").FieldsValue<{
|
|
12
|
+
id: import("@yume-chan/struct").NumberField<number>;
|
|
13
|
+
arg: import("@yume-chan/struct").NumberField<number>;
|
|
14
|
+
}>>;
|
|
15
|
+
static readonly FailResponse: import("@yume-chan/struct").Struct<{
|
|
16
|
+
message: import("@yume-chan/struct").Field<string, string, never, string>;
|
|
17
|
+
}, undefined, never>;
|
|
18
|
+
get position(): number;
|
|
19
|
+
get closed(): Promise<undefined>;
|
|
20
|
+
constructor(socket: Adb.Socket, bufferSize: number);
|
|
21
|
+
/**
|
|
22
|
+
* Start an idle timer that will close the socket after the specified duration.
|
|
23
|
+
* The timer is automatically cancelled when the socket is used.
|
|
24
|
+
* @param timeout The timeout in milliseconds
|
|
25
|
+
* @param callback The callback to invoke when the timeout expires
|
|
26
|
+
*/
|
|
27
|
+
startIdleTimer(timeout: number, callback: () => void): void;
|
|
28
|
+
/**
|
|
29
|
+
* Clear the idle timer.
|
|
30
|
+
*/
|
|
31
|
+
clearIdleTimer(): void;
|
|
32
|
+
flush(): Promise<void>;
|
|
33
|
+
write(data: Uint8Array): Promise<void>;
|
|
34
|
+
writeRequest(id: number, value: number | string | Uint8Array): Promise<void>;
|
|
35
|
+
readExactly(length: number): Promise<Uint8Array<ArrayBufferLike>>;
|
|
36
|
+
readResponse<T>(id: number, type: StructDeserializer<T>): Promise<T>;
|
|
37
|
+
readResponses<T>(expectedId: number, type: StructDeserializer<T>): AsyncGenerator<T, void, void>;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=socket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../../src/service/sync/socket.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGhF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAOxC,cAAM,YAAa,SAAQ,KAAK;CAAG;AACnC,OAAO,EAAE,YAAY,IAAI,KAAK,EAAE,CAAC;AAgBjC,qBAAa,MAAO,YAAW,kBAAkB;;IAC7C,MAAM,CAAC,QAAQ,CAAC,aAAa;;;;;;QAAiB;IAC9C,MAAM,CAAC,QAAQ,CAAC,YAAY;;yBAAgB;IAS5C,IAAI,QAAQ,WAEX;IAED,IAAI,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,CAE/B;gBAEW,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM;IAOlD;;;;;OAKG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI;IAKpD;;OAEG;IACH,cAAc;IAyBR,KAAK;IAaX,KAAK,CAAC,IAAI,EAAE,UAAU;IAIhB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU;IAkB5D,WAAW,CAAC,MAAM,EAAE,MAAM;IAO1B,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAgBtD,aAAa,CAAC,CAAC,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;IA6B1B,KAAK;CAKd"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { getUint32LittleEndian } from "@yume-chan/no-data-view";
|
|
2
|
+
import { BufferCombiner, BufferedReadableStream, clearTimeout, Consumable, setTimeout, tryCancel, } from "@yume-chan/stream-extra";
|
|
3
|
+
import { decodeUtf8, string, struct, u32 } from "@yume-chan/struct";
|
|
4
|
+
import { AutoResetEvent, encodeUtf8, unreachable } from "../../utils/index.js";
|
|
5
|
+
import { ResponseId } from "./id/index.js";
|
|
6
|
+
const NumberRequest = struct({ id: u32, arg: u32 }, { littleEndian: true });
|
|
7
|
+
class AdbSyncError extends Error {
|
|
8
|
+
}
|
|
9
|
+
export { AdbSyncError as Error };
|
|
10
|
+
const FailResponse = struct({ message: string(u32) }, {
|
|
11
|
+
littleEndian: true,
|
|
12
|
+
postDeserialize(value) {
|
|
13
|
+
throw new AdbSyncError(value.message);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
function i32ToHex(i) {
|
|
17
|
+
return "0x" + i.toString(16).padStart(8, "0");
|
|
18
|
+
}
|
|
19
|
+
export class Socket {
|
|
20
|
+
static NumberRequest = NumberRequest;
|
|
21
|
+
static FailResponse = FailResponse;
|
|
22
|
+
#socket;
|
|
23
|
+
#writer;
|
|
24
|
+
#readable;
|
|
25
|
+
#writeLock = new AutoResetEvent();
|
|
26
|
+
#combiner;
|
|
27
|
+
#idleTimeoutId = null;
|
|
28
|
+
get position() {
|
|
29
|
+
return this.#readable.position;
|
|
30
|
+
}
|
|
31
|
+
get closed() {
|
|
32
|
+
return this.#socket.closed;
|
|
33
|
+
}
|
|
34
|
+
constructor(socket, bufferSize) {
|
|
35
|
+
this.#socket = socket;
|
|
36
|
+
this.#writer = socket.writable.getWriter();
|
|
37
|
+
this.#readable = new BufferedReadableStream(socket.readable);
|
|
38
|
+
this.#combiner = new BufferCombiner(bufferSize);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Start an idle timer that will close the socket after the specified duration.
|
|
42
|
+
* The timer is automatically cancelled when the socket is used.
|
|
43
|
+
* @param timeout The timeout in milliseconds
|
|
44
|
+
* @param callback The callback to invoke when the timeout expires
|
|
45
|
+
*/
|
|
46
|
+
startIdleTimer(timeout, callback) {
|
|
47
|
+
this.clearIdleTimer();
|
|
48
|
+
this.#idleTimeoutId = setTimeout(callback, timeout);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Clear the idle timer.
|
|
52
|
+
*/
|
|
53
|
+
clearIdleTimer() {
|
|
54
|
+
if (this.#idleTimeoutId !== null) {
|
|
55
|
+
clearTimeout(this.#idleTimeoutId);
|
|
56
|
+
this.#idleTimeoutId = null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Write a packet to the socket.
|
|
61
|
+
* @param packet The packet to write. Must be smaller than the buffer size.
|
|
62
|
+
*/
|
|
63
|
+
#writeOne(packet) {
|
|
64
|
+
// `#combiner` will reuse the buffer, so we need to use the Consumable pattern
|
|
65
|
+
return Consumable.WritableStream.write(this.#writer, packet);
|
|
66
|
+
}
|
|
67
|
+
async #withWriteLock(callback) {
|
|
68
|
+
try {
|
|
69
|
+
await this.#writeLock.wait();
|
|
70
|
+
await callback();
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
this.#writeLock.notifyOne();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async flush() {
|
|
77
|
+
const buffer = this.#combiner.flush();
|
|
78
|
+
if (buffer) {
|
|
79
|
+
await this.#withWriteLock(() => this.#writeOne(buffer));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async #write(data) {
|
|
83
|
+
for (const buffer of this.#combiner.push(data)) {
|
|
84
|
+
await this.#writeOne(buffer);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
write(data) {
|
|
88
|
+
return this.#withWriteLock(() => this.#write(data));
|
|
89
|
+
}
|
|
90
|
+
async writeRequest(id, value) {
|
|
91
|
+
return this.#withWriteLock(async () => {
|
|
92
|
+
if (typeof value === "number") {
|
|
93
|
+
await this.#write(NumberRequest.serialize({ id, arg: value }));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (typeof value === "string") {
|
|
97
|
+
value = encodeUtf8(value);
|
|
98
|
+
}
|
|
99
|
+
await this.#write(NumberRequest.serialize({ id, arg: value.length }));
|
|
100
|
+
await this.#write(value);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async readExactly(length) {
|
|
104
|
+
// The request may still be in the internal buffer.
|
|
105
|
+
// Call `flush` to send it before starting reading
|
|
106
|
+
await this.flush();
|
|
107
|
+
return await this.#readable.readExactly(length);
|
|
108
|
+
}
|
|
109
|
+
async readResponse(id, type) {
|
|
110
|
+
const buffer = await this.readExactly(4);
|
|
111
|
+
switch (getUint32LittleEndian(buffer, 0)) {
|
|
112
|
+
case ResponseId.Fail:
|
|
113
|
+
await FailResponse.deserialize(this.#readable);
|
|
114
|
+
unreachable();
|
|
115
|
+
case id:
|
|
116
|
+
return await type.deserialize(this.#readable);
|
|
117
|
+
default:
|
|
118
|
+
// non-recoverable
|
|
119
|
+
throw new Error(`Expected '${id}', but got '${decodeUtf8(buffer)}'`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async *readResponses(expectedId, type) {
|
|
123
|
+
await this.flush();
|
|
124
|
+
while (true) {
|
|
125
|
+
const buffer = await this.#readable.readExactly(4);
|
|
126
|
+
const actualId = getUint32LittleEndian(buffer, 0);
|
|
127
|
+
switch (actualId) {
|
|
128
|
+
case ResponseId.Fail:
|
|
129
|
+
await FailResponse.deserialize(this.#readable);
|
|
130
|
+
unreachable();
|
|
131
|
+
case ResponseId.Done:
|
|
132
|
+
// `DONE` responses' size are always same as the request's normal response.
|
|
133
|
+
//
|
|
134
|
+
// For example, `DONE` responses for `LIST` requests are 16 bytes (same as `DENT` responses),
|
|
135
|
+
// but `DONE` responses for `STAT` requests are 12 bytes (same as `STAT` responses).
|
|
136
|
+
await this.#readable.readExactly(type.size);
|
|
137
|
+
return;
|
|
138
|
+
case expectedId:
|
|
139
|
+
yield await type.deserialize(this.#readable);
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
// non-recoverable
|
|
143
|
+
throw new Error(`Expected ${i32ToHex(expectedId)} or ${i32ToHex(ResponseId.Done)}, but got ${i32ToHex(actualId)}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async close() {
|
|
148
|
+
this.clearIdleTimer();
|
|
149
|
+
await tryCancel(this.#readable);
|
|
150
|
+
await this.#socket.close();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=socket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../../../src/service/sync/socket.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Adb } from "../adb.js";
|
|
2
2
|
/**
|
|
3
3
|
* ADB daemon checks for the following properties in the order of
|
|
4
4
|
*
|
|
@@ -18,7 +18,9 @@ export interface AdbTcpIpListenAddresses {
|
|
|
18
18
|
servicePort: number | undefined;
|
|
19
19
|
persistPort: number | undefined;
|
|
20
20
|
}
|
|
21
|
-
export declare class AdbTcpIpService
|
|
21
|
+
export declare class AdbTcpIpService {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(adb: Adb);
|
|
22
24
|
getListenAddresses(): Promise<AdbTcpIpListenAddresses>;
|
|
23
25
|
setPort(port: number): Promise<string>;
|
|
24
26
|
disable(): Promise<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcpip.d.ts","sourceRoot":"","sources":["../../src/service/tcpip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,uBAAuB;IACpC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AASD,qBAAa,eAAe;;gBAGZ,GAAG,EAAE,GAAG;IAId,kBAAkB,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAiBtD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAYtC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAOnC"}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { AdbServiceBase } from "./base.js";
|
|
2
1
|
function parsePort(value) {
|
|
3
2
|
if (!value || value === "0") {
|
|
4
3
|
return undefined;
|
|
5
4
|
}
|
|
6
5
|
return Number.parseInt(value, 10);
|
|
7
6
|
}
|
|
8
|
-
export class AdbTcpIpService
|
|
7
|
+
export class AdbTcpIpService {
|
|
8
|
+
#adb;
|
|
9
|
+
constructor(adb) {
|
|
10
|
+
this.#adb = adb;
|
|
11
|
+
}
|
|
9
12
|
async getListenAddresses() {
|
|
10
|
-
const serviceListenAddresses = await this
|
|
11
|
-
const servicePort = await this
|
|
12
|
-
const persistPort = await this
|
|
13
|
+
const serviceListenAddresses = await this.#adb.getProp("service.adb.listen_addrs");
|
|
14
|
+
const servicePort = await this.#adb.getProp("service.adb.tcp.port");
|
|
15
|
+
const persistPort = await this.#adb.getProp("persist.adb.tcp.port");
|
|
13
16
|
return {
|
|
14
17
|
serviceListenAddresses: serviceListenAddresses != ""
|
|
15
18
|
? serviceListenAddresses.split(",")
|
|
@@ -22,14 +25,14 @@ export class AdbTcpIpService extends AdbServiceBase {
|
|
|
22
25
|
if (port <= 0) {
|
|
23
26
|
throw new TypeError(`Invalid port ${port}`);
|
|
24
27
|
}
|
|
25
|
-
const output = await this
|
|
28
|
+
const output = await this.#adb.createSocketAndWait(`tcpip:${port}`);
|
|
26
29
|
if (output !== `restarting in TCP mode port: ${port}\n`) {
|
|
27
30
|
throw new Error(output);
|
|
28
31
|
}
|
|
29
32
|
return output;
|
|
30
33
|
}
|
|
31
34
|
async disable() {
|
|
32
|
-
const output = await this
|
|
35
|
+
const output = await this.#adb.createSocketAndWait("usb:");
|
|
33
36
|
if (output !== "restarting in USB mode\n") {
|
|
34
37
|
throw new Error(output);
|
|
35
38
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcpip.js","sourceRoot":"","sources":["../../src/service/tcpip.ts"],"names":[],"mappings":"AAsBA,SAAS,SAAS,CAAC,KAAa;IAC5B,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,OAAO,eAAe;IACf,IAAI,CAAM;IAEnB,YAAY,GAAQ;QAChB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,kBAAkB;QACpB,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAClD,0BAA0B,CAC7B,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACpE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAEpE,OAAO;YACH,sBAAsB,EAClB,sBAAsB,IAAI,EAAE;gBACxB,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC;gBACnC,CAAC,CAAC,EAAE;YACZ,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC;YACnC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC;SACtC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY;QACtB,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,SAAS,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,MAAM,KAAK,gCAAgC,IAAI,IAAI,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO;QACT,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,MAAM,KAAK,0BAA0B,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-buffer.d.ts","sourceRoot":"","sources":["../../src/utils/array-buffer.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"array-buffer.d.ts","sourceRoot":"","sources":["../../src/utils/array-buffer.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAO5E"}
|
|
@@ -2,8 +2,7 @@ export function toLocalUint8Array(value) {
|
|
|
2
2
|
if (value.buffer instanceof ArrayBuffer) {
|
|
3
3
|
return value;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return copy;
|
|
5
|
+
// This invokes the `constructor(Iterable<number>)` overload and copies the data
|
|
6
|
+
return new Uint8Array(value);
|
|
8
7
|
}
|
|
9
8
|
//# sourceMappingURL=array-buffer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-buffer.js","sourceRoot":"","sources":["../../src/utils/array-buffer.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAC/C,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW,EAAE,CAAC;QACtC,OAAO,KAAgC,CAAC;IAC5C,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"array-buffer.js","sourceRoot":"","sources":["../../src/utils/array-buffer.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAC/C,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW,EAAE,CAAC;QACtC,OAAO,KAAgC,CAAC;IAC5C,CAAC;IAED,gFAAgF;IAChF,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/utils/base64.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CACxC,WAAW,EAAE,MAAM,GACpB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,CAI/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;AACzE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/utils/base64.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CACxC,WAAW,EAAE,MAAM,GACpB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,CAI/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;AACzE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;AAmP5E,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAiEnE"}
|
package/esm/utils/base64.js
CHANGED
|
@@ -208,7 +208,18 @@ function encodeBackward(input, output, paddingLength) {
|
|
|
208
208
|
outputIndex -= 1;
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
function getCharIndex(input, offset) {
|
|
212
|
+
const charCode = input.charCodeAt(offset);
|
|
213
|
+
const index = charToIndex[charCode];
|
|
214
|
+
if (index === undefined) {
|
|
215
|
+
throw new Error("Invalid Base64 character: " + input[offset]);
|
|
216
|
+
}
|
|
217
|
+
return index;
|
|
218
|
+
}
|
|
211
219
|
export function decodeBase64(input) {
|
|
220
|
+
if (input.length % 4 !== 0) {
|
|
221
|
+
throw new Error("Invalid Base64 length: " + input.length);
|
|
222
|
+
}
|
|
212
223
|
let padding;
|
|
213
224
|
if (input[input.length - 2] === "=") {
|
|
214
225
|
padding = 2;
|
|
@@ -222,14 +233,15 @@ export function decodeBase64(input) {
|
|
|
222
233
|
const result = new Uint8Array((input.length / 4) * 3 - padding);
|
|
223
234
|
let sIndex = 0;
|
|
224
235
|
let dIndex = 0;
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
const loopEnd = input.length - (padding !== 0 ? 4 : 0);
|
|
237
|
+
while (sIndex < loopEnd) {
|
|
238
|
+
const a = getCharIndex(input, sIndex);
|
|
227
239
|
sIndex += 1;
|
|
228
|
-
const b =
|
|
240
|
+
const b = getCharIndex(input, sIndex);
|
|
229
241
|
sIndex += 1;
|
|
230
|
-
const c =
|
|
242
|
+
const c = getCharIndex(input, sIndex);
|
|
231
243
|
sIndex += 1;
|
|
232
|
-
const d =
|
|
244
|
+
const d = getCharIndex(input, sIndex);
|
|
233
245
|
sIndex += 1;
|
|
234
246
|
result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
|
|
235
247
|
dIndex += 1;
|
|
@@ -239,19 +251,19 @@ export function decodeBase64(input) {
|
|
|
239
251
|
dIndex += 1;
|
|
240
252
|
}
|
|
241
253
|
if (padding === 1) {
|
|
242
|
-
const a =
|
|
254
|
+
const a = getCharIndex(input, sIndex);
|
|
243
255
|
sIndex += 1;
|
|
244
|
-
const b =
|
|
256
|
+
const b = getCharIndex(input, sIndex);
|
|
245
257
|
sIndex += 1;
|
|
246
|
-
const c =
|
|
258
|
+
const c = getCharIndex(input, sIndex);
|
|
247
259
|
result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
|
|
248
260
|
dIndex += 1;
|
|
249
261
|
result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
|
|
250
262
|
}
|
|
251
263
|
else if (padding === 2) {
|
|
252
|
-
const a =
|
|
264
|
+
const a = getCharIndex(input, sIndex);
|
|
253
265
|
sIndex += 1;
|
|
254
|
-
const b =
|
|
266
|
+
const b = getCharIndex(input, sIndex);
|
|
255
267
|
result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
|
|
256
268
|
}
|
|
257
269
|
return result;
|