git-remote-ops 0.1.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/AGENTS.md +177 -0
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/esm/_dnt.shims.js +72 -0
- package/esm/cli.js +217 -0
- package/esm/client.js +439 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_errors.js +133 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_spread.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_utils.js +141 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/command.js +1861 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.js +357 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/mod.js +13 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/type.js +27 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.js +16 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.js +13 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.js +14 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/command.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/enum.js +24 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/file.js +12 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/integer.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/number.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/secret.js +7 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/string.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types.js +2 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.js +26 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_errors.js +129 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_utils.js +100 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.js +166 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/flags.js +750 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/mod.js +55 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.js +11 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.js +9 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/number.js +11 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/string.js +4 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types.js +1 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.js +16 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.js +11 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.js +25 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.js +18 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.js +11 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_layout.js +616 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_utils.js +79 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/border.js +18 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/cell.js +190 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/column.js +117 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/consume_words.js +64 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/mod.js +42 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/row.js +82 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/table.js +341 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.js +101 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.js +2 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +237 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2277 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +46 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +132 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.js +270 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.js +23 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +51 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +13 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +2 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +87 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.js +903 -0
- package/esm/deps/jsr.io/@std/text/1.0.18/closest_string.js +46 -0
- package/esm/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.js +127 -0
- package/esm/errors.js +38 -0
- package/esm/index.js +10 -0
- package/esm/logger.js +216 -0
- package/esm/objects/commit.js +47 -0
- package/esm/objects/index.js +2 -0
- package/esm/objects/tree.js +149 -0
- package/esm/pack/delta.js +179 -0
- package/esm/pack/index.js +3 -0
- package/esm/pack/objects.js +72 -0
- package/esm/pack/parser.js +304 -0
- package/esm/package.json +3 -0
- package/esm/protocol/index.js +3 -0
- package/esm/protocol/pkt_line.js +103 -0
- package/esm/protocol/refs.js +100 -0
- package/esm/protocol/upload_pack.js +259 -0
- package/esm/transport.js +128 -0
- package/esm/types.js +8 -0
- package/package.json +50 -0
- package/types/_dnt.shims.d.ts +16 -0
- package/types/_dnt.shims.d.ts.map +1 -0
- package/types/cli.d.ts +3 -0
- package/types/cli.d.ts.map +1 -0
- package/types/client.d.ts +108 -0
- package/types/client.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts +163 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts +71 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts +16 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts +15 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts +38 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts +1086 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts +33 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts +78 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts +51 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts +11 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts +6 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts +6 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts +161 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts +67 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts +17 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts +11 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts +154 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts +57 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts +170 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts +108 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts +26 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts +21 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts +155 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts +97 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts +30 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts +43 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts +67 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts +235 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts +40 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +23 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +4 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +9 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +39 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts +700 -0
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts +42 -0
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts +23 -0
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts.map +1 -0
- package/types/errors.d.ts +73 -0
- package/types/errors.d.ts.map +1 -0
- package/types/index.d.ts +14 -0
- package/types/index.d.ts.map +1 -0
- package/types/logger.d.ts +70 -0
- package/types/logger.d.ts.map +1 -0
- package/types/objects/commit.d.ts +23 -0
- package/types/objects/commit.d.ts.map +1 -0
- package/types/objects/index.d.ts +3 -0
- package/types/objects/index.d.ts.map +1 -0
- package/types/objects/tree.d.ts +49 -0
- package/types/objects/tree.d.ts.map +1 -0
- package/types/pack/delta.d.ts +47 -0
- package/types/pack/delta.d.ts.map +1 -0
- package/types/pack/index.d.ts +4 -0
- package/types/pack/index.d.ts.map +1 -0
- package/types/pack/objects.d.ts +53 -0
- package/types/pack/objects.d.ts.map +1 -0
- package/types/pack/parser.d.ts +61 -0
- package/types/pack/parser.d.ts.map +1 -0
- package/types/protocol/index.d.ts +4 -0
- package/types/protocol/index.d.ts.map +1 -0
- package/types/protocol/pkt_line.d.ts +44 -0
- package/types/protocol/pkt_line.d.ts.map +1 -0
- package/types/protocol/refs.d.ts +40 -0
- package/types/protocol/refs.d.ts.map +1 -0
- package/types/protocol/upload_pack.d.ts +45 -0
- package/types/protocol/upload_pack.d.ts.map +1 -0
- package/types/transport.d.ts +24 -0
- package/types/transport.d.ts.map +1 -0
- package/types/types.d.ts +121 -0
- package/types/types.d.ts.map +1 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Consumer-facing orientation for coding agents working **with** `git-remote-ops`. For
|
|
4
|
+
contributor-internal lore (parser invariants, harness boot), see `docs/`.
|
|
5
|
+
|
|
6
|
+
## What this library is
|
|
7
|
+
|
|
8
|
+
Read-only Git client over smart HTTP. No `.git` dir, no subprocess, no working tree. Fetches one
|
|
9
|
+
commit / one tree / one blob from a remote and hands back decoded bytes.
|
|
10
|
+
|
|
11
|
+
## What it is NOT
|
|
12
|
+
|
|
13
|
+
- Not a `git` replacement. No push, no working tree, no ref writes, no merges.
|
|
14
|
+
- Not a clone manager. No `have` negotiation, no incremental sync — every fetch is from-scratch with
|
|
15
|
+
`done`.
|
|
16
|
+
- Not streaming. Packs are held in memory in full.
|
|
17
|
+
|
|
18
|
+
If consumer needs writes or full clones, shell out to `git` instead.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { RemoteGit } from "jsr:@local/git-remote-ops";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Deno only. Requires `--allow-net`.
|
|
27
|
+
|
|
28
|
+
CLI:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
deno install --global -A -n git-remote-ops src/cli.ts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Core API
|
|
35
|
+
|
|
36
|
+
One class. All methods async. All return `Result<T, GitRemoteOpsError>` from
|
|
37
|
+
[`better-result`](https://jsr.io/@local/better-result) — never throw.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const client = new RemoteGit(url, { logger? , diagnostic? });
|
|
41
|
+
|
|
42
|
+
await client.discover(); // -> ServerProfile
|
|
43
|
+
await client.probe(verbose?); // -> ServerProfile (filter probe)
|
|
44
|
+
await client.lsRefs(); // -> Map<refName, sha>
|
|
45
|
+
await client.resolveRef(ref); // -> sha
|
|
46
|
+
await client.fetchCommit(ref, { depth?, filter?, parseFull? });
|
|
47
|
+
await client.fetchBlob(sha);
|
|
48
|
+
await client.fetchTree(sha);
|
|
49
|
+
await client.fetchTreeForCommit(ref, opts);
|
|
50
|
+
client.getObject(sha); // cache lookup, no network
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Result handling
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const r = await client.fetchBlob(sha);
|
|
57
|
+
if (r.isErr()) {
|
|
58
|
+
// narrow on _tag
|
|
59
|
+
if (r.error._tag === "TransportError") console.error(r.error.status);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const bytes = r.value;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Error tags: `PackParseError`, `ObjectDecodeError`, `PktLineError`, `UploadPackError`,
|
|
66
|
+
`TransportError`, `RefNotFoundError`, `ObjectNotFoundError`, `PathNotFoundError`. Union =
|
|
67
|
+
`GitRemoteOpsError`.
|
|
68
|
+
|
|
69
|
+
Never `try/catch` for control flow — these calls don't throw. Wrap user code that calls `.unwrap()`
|
|
70
|
+
if you want exceptions.
|
|
71
|
+
|
|
72
|
+
## Caching behaviour consumers should know
|
|
73
|
+
|
|
74
|
+
One `RemoteGit` instance keeps:
|
|
75
|
+
|
|
76
|
+
- One `ServerProfile` — populated on first call, reused after.
|
|
77
|
+
- All materialized objects in a `Map<sha, GitObject>`, **process-lifetime**.
|
|
78
|
+
|
|
79
|
+
Implications:
|
|
80
|
+
|
|
81
|
+
- Reuse instances across calls — commit → tree → blob dedupes `want`s.
|
|
82
|
+
- Don't hold an instance forever in long-running processes if memory matters. Throw it away when
|
|
83
|
+
done with that remote.
|
|
84
|
+
- Concurrent calls on one instance share the cache; no internal locking.
|
|
85
|
+
|
|
86
|
+
## Choosing options
|
|
87
|
+
|
|
88
|
+
| Goal | Recipe |
|
|
89
|
+
| --------------------------- | ----------------------------------------------------------------------------- |
|
|
90
|
+
| One commit's metadata | `fetchCommit(ref, { depth: 1, filter: "blob:none" })` |
|
|
91
|
+
| List files at snapshot | `fetchTreeForCommit(ref, { depth: 1, filter: "blob:none", parseFull: true })` |
|
|
92
|
+
| One known blob | `fetchBlob(sha)` (no profile probe needed) |
|
|
93
|
+
| Path → blob without network | `resolvePathToBlob` from `objects/tree.ts` against `client` object cache |
|
|
94
|
+
|
|
95
|
+
`depth: 1` + `filter: "blob:none"` is the cheap default. Both gracefully degrade if server doesn't
|
|
96
|
+
advertise the capability — depth drops, filter logs at info and proceeds.
|
|
97
|
+
|
|
98
|
+
## Logging
|
|
99
|
+
|
|
100
|
+
Library silent unless told otherwise.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Logger } from "jsr:@local/git-remote-ops";
|
|
104
|
+
|
|
105
|
+
const logger = new Logger({ level: "debug" });
|
|
106
|
+
const client = new RemoteGit(url, { logger });
|
|
107
|
+
// ...
|
|
108
|
+
console.error(logger.summary()); // metrics table
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Levels: `silent` < `info` < `debug` < `trace`. Metrics roll up across child loggers automatically.
|
|
112
|
+
|
|
113
|
+
## CLI surface
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
git-remote-ops probe <url>
|
|
117
|
+
git-remote-ops ls-refs <url>
|
|
118
|
+
git-remote-ops cat-commit <url> [--ref HEAD] [--depth N] [--filter SPEC | --no-filter]
|
|
119
|
+
git-remote-ops cat-tree <url> [--ref HEAD] [--depth N] [--filter SPEC | --no-filter]
|
|
120
|
+
[--tree-sha SHA]
|
|
121
|
+
git-remote-ops list-files <url> [--ref HEAD] [--depth N] [--filter SPEC | --no-filter]
|
|
122
|
+
[--details]
|
|
123
|
+
git-remote-ops cat-blob <url> <blob-sha>
|
|
124
|
+
|
|
125
|
+
Global: -q | -v | --debug | --stats
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Stdout = data. Stderr = logs + errors. Exit 1 on any `Result.err`.
|
|
129
|
+
|
|
130
|
+
Full reference: `docs/cli.md`.
|
|
131
|
+
|
|
132
|
+
## Common pitfalls
|
|
133
|
+
|
|
134
|
+
**Calling `fetchTree(commit.tree)` after `fetchCommit(ref)` with default options.** Default
|
|
135
|
+
`parseFull: false` only materializes the commit itself. Use `fetchTreeForCommit` or pass
|
|
136
|
+
`{ parseFull: true }` to `fetchCommit`.
|
|
137
|
+
|
|
138
|
+
**Expecting full history.** `depth: 1` (the CLI default) gives one commit. Drop depth for full
|
|
139
|
+
history; expect a much larger pack.
|
|
140
|
+
|
|
141
|
+
**Treating `RefNotFoundError` as fatal.** A 40-char hex sha is accepted even when not in the ad —
|
|
142
|
+
try direct sha if your ref is unusual.
|
|
143
|
+
|
|
144
|
+
**Confusing `getObject` with a fetch.** `getObject` only checks the cache. Returns `undefined` if
|
|
145
|
+
not yet materialized. No network call.
|
|
146
|
+
|
|
147
|
+
**Throwing away the client between calls.** Re-discovers, re-probes, re-fetches the same objects.
|
|
148
|
+
Reuse it.
|
|
149
|
+
|
|
150
|
+
## Where to look in source
|
|
151
|
+
|
|
152
|
+
| Concern | File |
|
|
153
|
+
| ---------------------- | ----------------------------- |
|
|
154
|
+
| Public API | `src/client.ts` |
|
|
155
|
+
| Types | `src/types.ts` |
|
|
156
|
+
| Errors | `src/errors.ts` |
|
|
157
|
+
| Logging / metrics | `src/logger.ts` |
|
|
158
|
+
| HTTP | `src/transport.ts` |
|
|
159
|
+
| Wire framing | `src/protocol/pkt_line.ts` |
|
|
160
|
+
| Ref / capability parse | `src/protocol/refs.ts` |
|
|
161
|
+
| Fetch req + sideband | `src/protocol/upload_pack.ts` |
|
|
162
|
+
| Packfile decode | `src/pack/parser.ts` |
|
|
163
|
+
| Delta application | `src/pack/delta.ts` |
|
|
164
|
+
| Pack constants + hash | `src/pack/objects.ts` |
|
|
165
|
+
| Commit decode | `src/objects/commit.ts` |
|
|
166
|
+
| Tree decode / walk | `src/objects/tree.ts` |
|
|
167
|
+
| CLI | `src/cli.ts` |
|
|
168
|
+
|
|
169
|
+
Every file carries a module-level JSDoc banner with intent. Every constant documented inline.
|
|
170
|
+
|
|
171
|
+
## Versioning
|
|
172
|
+
|
|
173
|
+
Pre-1.0. API may shift. Pin exact version in `deno.json` imports.
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
See `LICENSE`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Goulin Khoge
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# git-remote-ops
|
|
2
|
+
|
|
3
|
+
**Read-only Git over smart HTTP, without `git`.** A single Deno/TypeScript process speaks the same
|
|
4
|
+
wire protocol that `git fetch` does, then materializes the parts you actually want — one commit, one
|
|
5
|
+
tree, one file — straight into memory.
|
|
6
|
+
|
|
7
|
+
No `.git` directory. No subprocess. No filesystem state to clean up.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
deno run --allow-net jsr:@local/git-remote-ops/cli \
|
|
11
|
+
cat-blob https://github.com/torvalds/linux.git \
|
|
12
|
+
e8c39d0f… > Makefile
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The blob lands in `Makefile`. The local working set never grows past a few KB of cached pack
|
|
16
|
+
metadata.
|
|
17
|
+
|
|
18
|
+
## Why bother
|
|
19
|
+
|
|
20
|
+
A surprising amount of production code shells out to `git` just to read a file. That works, but it
|
|
21
|
+
forces a clone — every byte of every revision of every path — to retrieve one revision of one path.
|
|
22
|
+
On a large monorepo the clone is the entire latency budget.
|
|
23
|
+
|
|
24
|
+
The Git smart-HTTP protocol has supported targeted fetches for years. With shallow depth
|
|
25
|
+
(`--depth=1`) and partial-clone filters (`--filter=blob:none`, `--filter=tree:0`) you can ask the
|
|
26
|
+
server for _just the snapshot you care about_, often a few hundred kilobytes total. Mainline `git`
|
|
27
|
+
exposes this, but to use it you still need an on-disk clone and a forked process.
|
|
28
|
+
|
|
29
|
+
`git-remote-ops` is the thin client you'd write if you only ever did this one thing: a few hundred
|
|
30
|
+
lines of TypeScript that build the same `want`/`done` request `git` would, parse the packfile that
|
|
31
|
+
comes back, and hand you the decoded objects.
|
|
32
|
+
|
|
33
|
+
## What's in the box
|
|
34
|
+
|
|
35
|
+
Six subcommands, all read-only:
|
|
36
|
+
|
|
37
|
+
| Command | Does |
|
|
38
|
+
| ------------ | ------------------------------------------------------------- |
|
|
39
|
+
| `probe` | Capability sniff: protocol version, shallow, filter dialects. |
|
|
40
|
+
| `ls-refs` | List advertised refs as `<sha> <name>`. |
|
|
41
|
+
| `cat-commit` | Fetch + decode a commit object. |
|
|
42
|
+
| `cat-tree` | Fetch + decode a root tree (or a specific tree by sha). |
|
|
43
|
+
| `list-files` | Walk a snapshot and emit every path. |
|
|
44
|
+
| `cat-blob` | Stream one blob's raw bytes to stdout. |
|
|
45
|
+
|
|
46
|
+
And the same operations are available as a library:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { RemoteGit } from "jsr:@local/git-remote-ops";
|
|
50
|
+
|
|
51
|
+
const client = new RemoteGit("https://github.com/owner/repo.git");
|
|
52
|
+
const { sha, commit } = (await client.fetchCommit("HEAD")).unwrap();
|
|
53
|
+
const tree = (await client.fetchTree(commit.tree)).unwrap();
|
|
54
|
+
const blob = (await client.fetchBlob(tree[0].sha)).unwrap();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Every public call returns a `Result<T, GitRemoteOpsError>` from
|
|
58
|
+
[`better-result`](https://jsr.io/@local/better-result) — never throws.
|
|
59
|
+
|
|
60
|
+
## How it works
|
|
61
|
+
|
|
62
|
+
The work splits into four layers, and the codebase mirrors that split.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
┌──────────────────────────┐
|
|
66
|
+
src/client.ts ─→ │ RemoteGit (public API) │
|
|
67
|
+
└────────────┬─────────────┘
|
|
68
|
+
│
|
|
69
|
+
┌────────────────────────┼───────────────────────┐
|
|
70
|
+
▼ ▼ ▼
|
|
71
|
+
src/protocol/ src/pack/ src/objects/
|
|
72
|
+
pkt-line, refs, pack parser, delta, commit + tree
|
|
73
|
+
upload-pack zlib bridge decoders
|
|
74
|
+
│ ▲
|
|
75
|
+
▼ │
|
|
76
|
+
src/transport.ts ─────────────┘
|
|
77
|
+
(fetch wrappers)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 1. Transport — `src/transport.ts`
|
|
81
|
+
|
|
82
|
+
Two `fetch` calls do all the network work:
|
|
83
|
+
|
|
84
|
+
1. `GET /info/refs?service=git-upload-pack` — the ref advertisement.
|
|
85
|
+
2. `POST /git-upload-pack` — the actual fetch, body framed below.
|
|
86
|
+
|
|
87
|
+
Both helpers thread an optional `Logger` so byte counts and durations roll into the same metrics
|
|
88
|
+
struct the CLI's `--stats` flag prints.
|
|
89
|
+
|
|
90
|
+
### 2. Protocol — `src/protocol/`
|
|
91
|
+
|
|
92
|
+
**pkt-line framing.** Everything Git sends over HTTP is wrapped in a 4-byte ASCII-hex length prefix.
|
|
93
|
+
Length `0000` is a flush; `0001` and `0002` are v2 control packets. `parsePktLines` walks a buffer
|
|
94
|
+
end-to-end, returning subarray views — no payload bytes are copied. Trailing `\n`s are preserved
|
|
95
|
+
because some callers care.
|
|
96
|
+
|
|
97
|
+
**Ref advertisement.** v0/v1 puts capabilities NUL-separated on the first ref line; v2 puts them on
|
|
98
|
+
standalone pkt-lines after `version 2`. We parse both, merge the capability sets, and prefer v2 when
|
|
99
|
+
both are advertised.
|
|
100
|
+
|
|
101
|
+
**`git-upload-pack` request.** A `want <sha>` line per object, an optional `deepen <n>` for shallow,
|
|
102
|
+
an optional `filter <spec>` for partial-clone, a flush, then `done`. The v2 encoder adds a
|
|
103
|
+
`command=fetch` header section and turns capabilities into separate argument lines instead of riding
|
|
104
|
+
the first `want`.
|
|
105
|
+
|
|
106
|
+
**Sideband demux.** The response is itself a stream of pkt-lines; each data line starts with a
|
|
107
|
+
channel byte. Channel 1 is the packfile, channel 2 is human-readable progress, channel 3 is fatal
|
|
108
|
+
stderr. `extractPack` looks at the first real data line, picks the right strategy (raw `PACK`
|
|
109
|
+
signature, sideband, or PACK-search fallback), and returns the concatenated channel-1 bytes.
|
|
110
|
+
|
|
111
|
+
### 3. Packfile — `src/pack/`
|
|
112
|
+
|
|
113
|
+
A packfile is `PACK` + version + count + N variable-length object entries + a trailing SHA-1. Each
|
|
114
|
+
entry has a type/size header (a varint with a 3-bit type field jammed into the first byte) followed
|
|
115
|
+
by a zlib-compressed body.
|
|
116
|
+
|
|
117
|
+
The parser walks entries in order. For non-delta types it inflates and hashes the body in one shot.
|
|
118
|
+
For deltas — two flavours, `OBJ_OFS_DELTA` (base referenced by negative byte offset) and
|
|
119
|
+
`OBJ_REF_DELTA` (base referenced by 20-byte sha) — it applies the delta against the resolved base
|
|
120
|
+
and re-hashes the reconstructed object.
|
|
121
|
+
|
|
122
|
+
Two implementation notes worth flagging:
|
|
123
|
+
|
|
124
|
+
**zlib boundaries.** Multiple deflate streams sit back-to-back inside the pack with no length
|
|
125
|
+
prefix. The streaming API doesn't tell you how many input bytes a single decode consumed, so we
|
|
126
|
+
reach into `node:zlib`'s `_processChunk` and read `bytesWritten` to advance the cursor. It's an
|
|
127
|
+
implementation detail of Node's zlib binding, but it's a stable one, and the alternative is parsing
|
|
128
|
+
deflate headers ourselves.
|
|
129
|
+
|
|
130
|
+
**Targeted bailout.** If you only need a single commit, the parser accepts a `targets` set and
|
|
131
|
+
returns as soon as those shas are materialized — even mid-pack. On a large snapshot pack that's the
|
|
132
|
+
difference between parsing five megabytes of objects and parsing fifty kilobytes.
|
|
133
|
+
|
|
134
|
+
**Delta application.** The delta stream is a tiny opcode language: "copy `n` bytes from base at
|
|
135
|
+
offset `o`" or "insert these `n` literal bytes". A size of zero on a copy opcode means 64 KiB.
|
|
136
|
+
Out-of-bounds copies become typed errors, never silent corruption.
|
|
137
|
+
|
|
138
|
+
### 4. Objects — `src/objects/`
|
|
139
|
+
|
|
140
|
+
Commit and tree decoders. Both inputs are the _uncompressed_ bodies produced by layer 3; neither
|
|
141
|
+
parser cares how the bytes got there.
|
|
142
|
+
|
|
143
|
+
A tree is `<mode> <name>\0<sha20>` repeated, with no length prefix. A commit is RFC822-ish headers +
|
|
144
|
+
blank line + free-form message; we keep `tree`, first `parent`, `author`, `committer`. Multiple
|
|
145
|
+
`parent` lines (merge commits) collapse to the first because this client only walks toward snapshots
|
|
146
|
+
— never along history.
|
|
147
|
+
|
|
148
|
+
`walkTree` and `resolvePathToBlob` round out the layer for callers that want to flatten a tree or
|
|
149
|
+
resolve `path/to/file` to a blob sha without touching the network.
|
|
150
|
+
|
|
151
|
+
### 5. The client — `src/client.ts`
|
|
152
|
+
|
|
153
|
+
`RemoteGit` ties the layers together and caches two things across calls:
|
|
154
|
+
|
|
155
|
+
- A `ServerProfile` (refs + capabilities + filter probe results), populated lazily on the first call
|
|
156
|
+
and shared by everything after.
|
|
157
|
+
- Every materialized object, in a process-lifetime `Map`. Subsequent fetches dedupe `want` lists
|
|
158
|
+
against this map, so a typical commit → tree → blob sequence only pays the network cost for new
|
|
159
|
+
objects.
|
|
160
|
+
|
|
161
|
+
There's a small bit of negotiation logic: shallow depth is dropped if the server didn't advertise
|
|
162
|
+
`shallow`; filters are dropped (with an info log) if the server didn't advertise `filter`. `probe()`
|
|
163
|
+
exists because some servers _advertise_ filter support but don't honour it — we send minimal-cost
|
|
164
|
+
test fetches with `blob:none` and `tree:0` and look at the returned pack to find out.
|
|
165
|
+
|
|
166
|
+
## Errors
|
|
167
|
+
|
|
168
|
+
Every public function returns `Result<T, E>`. Errors are tagged classes from `better-result`, so you
|
|
169
|
+
can narrow on `_tag` and pull structured fields off:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const result = await client.fetchBlob(sha);
|
|
173
|
+
if (result.isErr()) {
|
|
174
|
+
switch (result.error._tag) {
|
|
175
|
+
case "TransportError": // .status, .url, .method available
|
|
176
|
+
case "PackParseError": // .offset, .reason
|
|
177
|
+
case "ObjectNotFoundError": // .sha
|
|
178
|
+
// …
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The full union is exported as `GitRemoteOpsError`. See `src/errors.ts`.
|
|
184
|
+
|
|
185
|
+
## Observability
|
|
186
|
+
|
|
187
|
+
The bundled `Logger` does three jobs at once:
|
|
188
|
+
|
|
189
|
+
- Levelled messages (`info`, `debug`, `trace`) with namespaced children.
|
|
190
|
+
- Cumulative metrics: HTTP request count / bytes / time, pack objects by type / bytes / parse time.
|
|
191
|
+
- An aligned summary table for `--stats`.
|
|
192
|
+
|
|
193
|
+
The library never logs above `info` unless you ask. Pass a configured `Logger` via
|
|
194
|
+
`new RemoteGit(url, { logger })`, or hand it a `diagnostic` callback and the constructor will route
|
|
195
|
+
debug-level lines to it.
|
|
196
|
+
|
|
197
|
+
## CLI
|
|
198
|
+
|
|
199
|
+
```text
|
|
200
|
+
git-remote-ops <command> [options] <url>
|
|
201
|
+
|
|
202
|
+
Global flags:
|
|
203
|
+
-q, --quiet silent
|
|
204
|
+
-v, --verbose debug
|
|
205
|
+
--debug trace
|
|
206
|
+
--stats print metrics summary after completion
|
|
207
|
+
|
|
208
|
+
probe <url>
|
|
209
|
+
ls-refs <url>
|
|
210
|
+
cat-commit <url> [--ref HEAD] [--depth 1] [--filter blob:none | --no-filter]
|
|
211
|
+
cat-tree <url> [--ref HEAD] [--depth 1] [--filter blob:none | --no-filter]
|
|
212
|
+
[--tree-sha <sha>]
|
|
213
|
+
list-files <url> [--ref HEAD] [--depth 1] [--filter blob:none | --no-filter]
|
|
214
|
+
[--details]
|
|
215
|
+
cat-blob <url> <blob-sha>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
See `docs/cli.md` for the long-form reference.
|
|
219
|
+
|
|
220
|
+
## Development
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
deno task check # type-check
|
|
224
|
+
deno task lint
|
|
225
|
+
deno task fmt:check
|
|
226
|
+
deno task test # unit tests (no network)
|
|
227
|
+
deno task test:integration # spins up a local git server
|
|
228
|
+
deno task verify # fmt + lint + check, what CI runs
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Tests for each layer live next to their code as `*.test.ts`. The integration tests under
|
|
232
|
+
`src/testing/integration/` exercise a real `git-upload-pack` talking to the client — see
|
|
233
|
+
`docs/git-server-harness-AGENTS.md` for how the harness boots.
|
|
234
|
+
|
|
235
|
+
## Limitations
|
|
236
|
+
|
|
237
|
+
By design this client only does fetches. It can't push, can't write to a working tree, can't manage
|
|
238
|
+
refs. It also makes no attempt to negotiate `have` lines — every request is a from-scratch fetch
|
|
239
|
+
with `done`, on the assumption that you're after small slices of remote history rather than
|
|
240
|
+
incrementally syncing a clone.
|
|
241
|
+
|
|
242
|
+
The packfile is held in memory in full. For large monorepos that fits in practice (kilobytes with
|
|
243
|
+
`blob:none` + `--depth=1`), but a streaming parser would be a reasonable evolution.
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
See `LICENSE`.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Deno } from "@deno/shim-deno";
|
|
2
|
+
export { Deno } from "@deno/shim-deno";
|
|
3
|
+
import { crypto } from "@deno/shim-crypto";
|
|
4
|
+
export { crypto } from "@deno/shim-crypto";
|
|
5
|
+
import { fetch, File, FormData, Headers, Request, Response } from "undici";
|
|
6
|
+
export { fetch, File, FormData, Headers, Request, Response } from "undici";
|
|
7
|
+
const dntGlobals = {
|
|
8
|
+
Deno,
|
|
9
|
+
crypto,
|
|
10
|
+
fetch,
|
|
11
|
+
File,
|
|
12
|
+
FormData,
|
|
13
|
+
Headers,
|
|
14
|
+
Request,
|
|
15
|
+
Response,
|
|
16
|
+
};
|
|
17
|
+
export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
|
|
18
|
+
function createMergeProxy(baseObj, extObj) {
|
|
19
|
+
return new Proxy(baseObj, {
|
|
20
|
+
get(_target, prop, _receiver) {
|
|
21
|
+
if (prop in extObj) {
|
|
22
|
+
return extObj[prop];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return baseObj[prop];
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
set(_target, prop, value) {
|
|
29
|
+
if (prop in extObj) {
|
|
30
|
+
delete extObj[prop];
|
|
31
|
+
}
|
|
32
|
+
baseObj[prop] = value;
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
deleteProperty(_target, prop) {
|
|
36
|
+
let success = false;
|
|
37
|
+
if (prop in extObj) {
|
|
38
|
+
delete extObj[prop];
|
|
39
|
+
success = true;
|
|
40
|
+
}
|
|
41
|
+
if (prop in baseObj) {
|
|
42
|
+
delete baseObj[prop];
|
|
43
|
+
success = true;
|
|
44
|
+
}
|
|
45
|
+
return success;
|
|
46
|
+
},
|
|
47
|
+
ownKeys(_target) {
|
|
48
|
+
const baseKeys = Reflect.ownKeys(baseObj);
|
|
49
|
+
const extKeys = Reflect.ownKeys(extObj);
|
|
50
|
+
const extKeysSet = new Set(extKeys);
|
|
51
|
+
return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
|
|
52
|
+
},
|
|
53
|
+
defineProperty(_target, prop, desc) {
|
|
54
|
+
if (prop in extObj) {
|
|
55
|
+
delete extObj[prop];
|
|
56
|
+
}
|
|
57
|
+
Reflect.defineProperty(baseObj, prop, desc);
|
|
58
|
+
return true;
|
|
59
|
+
},
|
|
60
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
61
|
+
if (prop in extObj) {
|
|
62
|
+
return Reflect.getOwnPropertyDescriptor(extObj, prop);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
return Reflect.getOwnPropertyDescriptor(baseObj, prop);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
has(_target, prop) {
|
|
69
|
+
return prop in extObj || prop in baseObj;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|