@struktoai/mirage-node 0.0.3-alpha.0 → 0.0.3
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/README.md +1 -1
- package/dist/{aliyun-TMZRUYCG.js → aliyun-JMJ3PFYY.js} +3 -3
- package/dist/{backblaze-OHW57DLK.js → backblaze-TDFD23QO.js} +3 -3
- package/dist/{box-UXTCAFOZ.js → box-GQ2U2R6R.js} +2 -2
- package/dist/{ceph-TNN4I2FT.js → ceph-S2VOYO6G.js} +3 -3
- package/dist/{chunk-FXFDBF3P.js → chunk-3WIO7NBR.js} +2 -2
- package/dist/{chunk-O7ODGJYL.js → chunk-47AVIIOT.js} +2 -2
- package/dist/{chunk-Q6CDMOM6.js → chunk-7CW3BMPH.js} +2 -2
- package/dist/{chunk-E7RW3SBV.js → chunk-A7IVFIOP.js} +2 -2
- package/dist/chunk-A7IVFIOP.js.map +1 -0
- package/dist/{chunk-3T3RMDNX.js → chunk-AUHSTJJ3.js} +2 -2
- package/dist/{chunk-PJBQKMCD.js → chunk-DM4GSE26.js} +2 -2
- package/dist/{chunk-5DLOHQJ2.js → chunk-EM4J5EQS.js} +2 -2
- package/dist/chunk-EM4J5EQS.js.map +1 -0
- package/dist/{chunk-ABTEGAFB.js → chunk-EZQ5HBAC.js} +2 -2
- package/dist/chunk-EZQ5HBAC.js.map +1 -0
- package/dist/{chunk-KTNDT45N.js → chunk-FQ33BYFR.js} +2 -2
- package/dist/{chunk-YAVGCQUP.js → chunk-G2WCEUQL.js} +2 -2
- package/dist/chunk-G2WCEUQL.js.map +1 -0
- package/dist/{chunk-RLGWMJD3.js → chunk-GCFYZSVR.js} +133 -3
- package/dist/chunk-GCFYZSVR.js.map +1 -0
- package/dist/{chunk-NHS7WLEQ.js → chunk-GS5AUKUO.js} +2 -2
- package/dist/chunk-GS5AUKUO.js.map +1 -0
- package/dist/{chunk-BYTU2YC3.js → chunk-HGCRXJGP.js} +2 -2
- package/dist/{chunk-G5BZE7UA.js → chunk-HJJMP6IX.js} +2 -2
- package/dist/{chunk-IQVNVTOP.js → chunk-I5THIMPP.js} +2 -2
- package/dist/chunk-IDYHQQOH.js +1095 -0
- package/dist/chunk-IDYHQQOH.js.map +1 -0
- package/dist/{chunk-C6NHFMIP.js → chunk-IK2L4EN3.js} +2 -2
- package/dist/{chunk-LYDMMNL2.js → chunk-JAGJTM3Q.js} +2 -2
- package/dist/chunk-JAGJTM3Q.js.map +1 -0
- package/dist/{chunk-A7X4L4JM.js → chunk-JCC4CU2I.js} +2 -2
- package/dist/chunk-JCC4CU2I.js.map +1 -0
- package/dist/{chunk-AJICZLHT.js → chunk-KPULTUOK.js} +2 -2
- package/dist/{chunk-YPT4JBUY.js → chunk-LV2G7VHL.js} +2 -2
- package/dist/chunk-LV2G7VHL.js.map +1 -0
- package/dist/{chunk-C6NHEDHY.js → chunk-M5FVUIYP.js} +2 -2
- package/dist/chunk-M5FVUIYP.js.map +1 -0
- package/dist/{chunk-HEHERHQ5.js → chunk-MPCCRRE6.js} +2 -2
- package/dist/chunk-MPCCRRE6.js.map +1 -0
- package/dist/{chunk-RQYEEA2O.js → chunk-N5FSLVKO.js} +2 -2
- package/dist/{chunk-CASCUFK2.js → chunk-NOHWIBRX.js} +2 -2
- package/dist/chunk-NOHWIBRX.js.map +1 -0
- package/dist/{chunk-TRTUHCS4.js → chunk-QCZ2XUKH.js} +2 -2
- package/dist/chunk-QCZ2XUKH.js.map +1 -0
- package/dist/{chunk-3IJSIVKT.js → chunk-QQBJC2FQ.js} +2 -2
- package/dist/{chunk-JZQHKDSY.js → chunk-RNQN2FOU.js} +2 -2
- package/dist/chunk-RNQN2FOU.js.map +1 -0
- package/dist/{chunk-DTAY7LPC.js → chunk-S5OVP467.js} +2 -2
- package/dist/chunk-S5OVP467.js.map +1 -0
- package/dist/{chunk-5YOCVEUB.js → chunk-SWCDFEUK.js} +2 -2
- package/dist/chunk-SWCDFEUK.js.map +1 -0
- package/dist/{chunk-MHCMHKM6.js → chunk-TA3WMOMU.js} +2 -2
- package/dist/chunk-TA3WMOMU.js.map +1 -0
- package/dist/{chunk-WSGEIVY3.js → chunk-TURD42QO.js} +101 -85
- package/dist/chunk-TURD42QO.js.map +1 -0
- package/dist/{chunk-WL7HS7EM.js → chunk-UINQOUZR.js} +2 -2
- package/dist/{chunk-A4Z6DZ22.js → chunk-VWKUT4CW.js} +2 -2
- package/dist/chunk-VWKUT4CW.js.map +1 -0
- package/dist/{chunk-ERELJ7BS.js → chunk-WAR4Q2NM.js} +2 -2
- package/dist/chunk-WAR4Q2NM.js.map +1 -0
- package/dist/{chunk-5HCVKTP3.js → chunk-WHFUWWI6.js} +92 -81
- package/dist/chunk-WHFUWWI6.js.map +1 -0
- package/dist/{chunk-HQ4KWN76.js → chunk-X3G37FXT.js} +2 -2
- package/dist/{chunk-OYV2DN66.js → chunk-X5HF2OFP.js} +2 -2
- package/dist/chunk-XWVDS66D.js +963 -0
- package/dist/chunk-XWVDS66D.js.map +1 -0
- package/dist/{chunk-L6JPBJAS.js → chunk-YAHRT6MB.js} +2 -2
- package/dist/{chunk-XRU5WXZX.js → chunk-ZEGAMJO2.js} +2 -2
- package/dist/chunk-ZEGAMJO2.js.map +1 -0
- package/dist/{chunk-B6SXRCBO.js → chunk-ZGSER5TG.js} +2 -2
- package/dist/databricks_volume-7XOUYSTY.js +7 -0
- package/dist/{digitalocean-6SPR4S7V.js → digitalocean-3CQ4CPPZ.js} +3 -3
- package/dist/{discord-SAV2RBJV.js → discord-BG7OSRJG.js} +2 -2
- package/dist/{disk-POACMF4G.js → disk-XVLBCVKE.js} +2 -2
- package/dist/{dropbox-CQ7MTYX2.js → dropbox-74GYLV3R.js} +2 -2
- package/dist/{email-KBQ7CXS7.js → email-5IZ7OBQ4.js} +2 -2
- package/dist/{gcs-SMIE4VMT.js → gcs-EMEYU2XT.js} +3 -3
- package/dist/{gdocs-X5Y2SIQX.js → gdocs-R67TDPON.js} +2 -2
- package/dist/{gdrive-SIQPRIGI.js → gdrive-PRN2ALRK.js} +2 -2
- package/dist/{github-KBHWANKQ.js → github-DV7E6OFV.js} +2 -2
- package/dist/{github_ci-HPITNK37.js → github_ci-Q554V5PA.js} +2 -2
- package/dist/{gmail-DKHAGJNX.js → gmail-OLN2LT4O.js} +2 -2
- package/dist/{gsheets-ZSUDIWGK.js → gsheets-H4RYMQJ5.js} +2 -2
- package/dist/{gslides-GYXM7IMJ.js → gslides-YLCHKJOM.js} +2 -2
- package/dist/{hf_buckets-RIOMV7WG.js → hf_buckets-DTKXKKFF.js} +3 -3
- package/dist/{hf_datasets-QF4BQ3OK.js → hf_datasets-55C4APKR.js} +3 -3
- package/dist/{hf_models-62GC2HPZ.js → hf_models-RO5JR36V.js} +3 -3
- package/dist/{hf_spaces-NVSMUNRM.js → hf_spaces-ZVZ3EDRX.js} +3 -3
- package/dist/index.d.ts +110 -44
- package/dist/index.js +520 -232
- package/dist/index.js.map +1 -1
- package/dist/{langfuse-HUAYVPHF.js → langfuse-ACASJZ7O.js} +2 -2
- package/dist/{linear-2MM55KBC.js → linear-IC37LZV7.js} +2 -2
- package/dist/{minio-L3XE6PQS.js → minio-HZ576XFQ.js} +3 -3
- package/dist/mongodb-JVR62OIO.js +7 -0
- package/dist/{notion-UK4GTMT4.js → notion-HKRPQMJS.js} +2 -2
- package/dist/{oci-NURLWPL2.js → oci-ZLVECXTW.js} +3 -3
- package/dist/postgres-P36Z2YN4.js +7 -0
- package/dist/{qingstor-W55D5YFO.js → qingstor-YLP6K3L4.js} +3 -3
- package/dist/{r2-FSZK7IFI.js → r2-RPK25ANI.js} +3 -3
- package/dist/{redis-S6GIPA4Z.js → redis-V5ULXULL.js} +2 -2
- package/dist/{s3-GMPUJ65D.js → s3-4OIOCAAT.js} +2 -2
- package/dist/{scaleway-5VM55Y6D.js → scaleway-CCWCLUHB.js} +3 -3
- package/dist/{seaweedfs-J3EPUEPE.js → seaweedfs-QSWKF2FN.js} +3 -3
- package/dist/{slack-FVBXY7KD.js → slack-YPS7PII3.js} +2 -2
- package/dist/{ssh-GCXETJ3Z.js → ssh-YFP3SMTJ.js} +2 -2
- package/dist/{supabase-HLWNHBBE.js → supabase-6CFTOKGZ.js} +3 -3
- package/dist/{tencent-YDO73XBD.js → tencent-IWZZOSQ4.js} +3 -3
- package/dist/{trello-CQ53BQUL.js → trello-XYKWZD6P.js} +2 -2
- package/dist/{wasabi-SOZKPMRQ.js → wasabi-6Z4DC5S5.js} +3 -3
- package/package.json +7 -5
- package/dist/chunk-5DLOHQJ2.js.map +0 -1
- package/dist/chunk-5HCVKTP3.js.map +0 -1
- package/dist/chunk-5YOCVEUB.js.map +0 -1
- package/dist/chunk-A4Z6DZ22.js.map +0 -1
- package/dist/chunk-A7X4L4JM.js.map +0 -1
- package/dist/chunk-ABTEGAFB.js.map +0 -1
- package/dist/chunk-C6NHEDHY.js.map +0 -1
- package/dist/chunk-CASCUFK2.js.map +0 -1
- package/dist/chunk-DTAY7LPC.js.map +0 -1
- package/dist/chunk-E7RW3SBV.js.map +0 -1
- package/dist/chunk-ERELJ7BS.js.map +0 -1
- package/dist/chunk-HEHERHQ5.js.map +0 -1
- package/dist/chunk-JZQHKDSY.js.map +0 -1
- package/dist/chunk-LYDMMNL2.js.map +0 -1
- package/dist/chunk-MHCMHKM6.js.map +0 -1
- package/dist/chunk-N72CAZEH.js +0 -1990
- package/dist/chunk-N72CAZEH.js.map +0 -1
- package/dist/chunk-NHS7WLEQ.js.map +0 -1
- package/dist/chunk-PBBG7VFT.js +0 -1896
- package/dist/chunk-PBBG7VFT.js.map +0 -1
- package/dist/chunk-RLGWMJD3.js.map +0 -1
- package/dist/chunk-TRTUHCS4.js.map +0 -1
- package/dist/chunk-WSGEIVY3.js.map +0 -1
- package/dist/chunk-XRU5WXZX.js.map +0 -1
- package/dist/chunk-YAVGCQUP.js.map +0 -1
- package/dist/chunk-YPT4JBUY.js.map +0 -1
- package/dist/databricks_volume-HNQ4DJVJ.js +0 -7
- package/dist/mongodb-ZOX4FRHJ.js +0 -7
- package/dist/postgres-JNFMPAO2.js +0 -7
- /package/dist/{aliyun-TMZRUYCG.js.map → aliyun-JMJ3PFYY.js.map} +0 -0
- /package/dist/{backblaze-OHW57DLK.js.map → backblaze-TDFD23QO.js.map} +0 -0
- /package/dist/{box-UXTCAFOZ.js.map → box-GQ2U2R6R.js.map} +0 -0
- /package/dist/{ceph-TNN4I2FT.js.map → ceph-S2VOYO6G.js.map} +0 -0
- /package/dist/{chunk-FXFDBF3P.js.map → chunk-3WIO7NBR.js.map} +0 -0
- /package/dist/{chunk-O7ODGJYL.js.map → chunk-47AVIIOT.js.map} +0 -0
- /package/dist/{chunk-Q6CDMOM6.js.map → chunk-7CW3BMPH.js.map} +0 -0
- /package/dist/{chunk-3T3RMDNX.js.map → chunk-AUHSTJJ3.js.map} +0 -0
- /package/dist/{chunk-PJBQKMCD.js.map → chunk-DM4GSE26.js.map} +0 -0
- /package/dist/{chunk-KTNDT45N.js.map → chunk-FQ33BYFR.js.map} +0 -0
- /package/dist/{chunk-BYTU2YC3.js.map → chunk-HGCRXJGP.js.map} +0 -0
- /package/dist/{chunk-G5BZE7UA.js.map → chunk-HJJMP6IX.js.map} +0 -0
- /package/dist/{chunk-IQVNVTOP.js.map → chunk-I5THIMPP.js.map} +0 -0
- /package/dist/{chunk-C6NHFMIP.js.map → chunk-IK2L4EN3.js.map} +0 -0
- /package/dist/{chunk-AJICZLHT.js.map → chunk-KPULTUOK.js.map} +0 -0
- /package/dist/{chunk-RQYEEA2O.js.map → chunk-N5FSLVKO.js.map} +0 -0
- /package/dist/{chunk-3IJSIVKT.js.map → chunk-QQBJC2FQ.js.map} +0 -0
- /package/dist/{chunk-WL7HS7EM.js.map → chunk-UINQOUZR.js.map} +0 -0
- /package/dist/{chunk-HQ4KWN76.js.map → chunk-X3G37FXT.js.map} +0 -0
- /package/dist/{chunk-OYV2DN66.js.map → chunk-X5HF2OFP.js.map} +0 -0
- /package/dist/{chunk-L6JPBJAS.js.map → chunk-YAHRT6MB.js.map} +0 -0
- /package/dist/{chunk-B6SXRCBO.js.map → chunk-ZGSER5TG.js.map} +0 -0
- /package/dist/{databricks_volume-HNQ4DJVJ.js.map → databricks_volume-7XOUYSTY.js.map} +0 -0
- /package/dist/{digitalocean-6SPR4S7V.js.map → digitalocean-3CQ4CPPZ.js.map} +0 -0
- /package/dist/{discord-SAV2RBJV.js.map → discord-BG7OSRJG.js.map} +0 -0
- /package/dist/{disk-POACMF4G.js.map → disk-XVLBCVKE.js.map} +0 -0
- /package/dist/{dropbox-CQ7MTYX2.js.map → dropbox-74GYLV3R.js.map} +0 -0
- /package/dist/{email-KBQ7CXS7.js.map → email-5IZ7OBQ4.js.map} +0 -0
- /package/dist/{gcs-SMIE4VMT.js.map → gcs-EMEYU2XT.js.map} +0 -0
- /package/dist/{gdocs-X5Y2SIQX.js.map → gdocs-R67TDPON.js.map} +0 -0
- /package/dist/{gdrive-SIQPRIGI.js.map → gdrive-PRN2ALRK.js.map} +0 -0
- /package/dist/{github-KBHWANKQ.js.map → github-DV7E6OFV.js.map} +0 -0
- /package/dist/{github_ci-HPITNK37.js.map → github_ci-Q554V5PA.js.map} +0 -0
- /package/dist/{gmail-DKHAGJNX.js.map → gmail-OLN2LT4O.js.map} +0 -0
- /package/dist/{gsheets-ZSUDIWGK.js.map → gsheets-H4RYMQJ5.js.map} +0 -0
- /package/dist/{gslides-GYXM7IMJ.js.map → gslides-YLCHKJOM.js.map} +0 -0
- /package/dist/{hf_buckets-RIOMV7WG.js.map → hf_buckets-DTKXKKFF.js.map} +0 -0
- /package/dist/{hf_datasets-QF4BQ3OK.js.map → hf_datasets-55C4APKR.js.map} +0 -0
- /package/dist/{hf_models-62GC2HPZ.js.map → hf_models-RO5JR36V.js.map} +0 -0
- /package/dist/{hf_spaces-NVSMUNRM.js.map → hf_spaces-ZVZ3EDRX.js.map} +0 -0
- /package/dist/{langfuse-HUAYVPHF.js.map → langfuse-ACASJZ7O.js.map} +0 -0
- /package/dist/{linear-2MM55KBC.js.map → linear-IC37LZV7.js.map} +0 -0
- /package/dist/{minio-L3XE6PQS.js.map → minio-HZ576XFQ.js.map} +0 -0
- /package/dist/{mongodb-ZOX4FRHJ.js.map → mongodb-JVR62OIO.js.map} +0 -0
- /package/dist/{notion-UK4GTMT4.js.map → notion-HKRPQMJS.js.map} +0 -0
- /package/dist/{oci-NURLWPL2.js.map → oci-ZLVECXTW.js.map} +0 -0
- /package/dist/{postgres-JNFMPAO2.js.map → postgres-P36Z2YN4.js.map} +0 -0
- /package/dist/{qingstor-W55D5YFO.js.map → qingstor-YLP6K3L4.js.map} +0 -0
- /package/dist/{r2-FSZK7IFI.js.map → r2-RPK25ANI.js.map} +0 -0
- /package/dist/{redis-S6GIPA4Z.js.map → redis-V5ULXULL.js.map} +0 -0
- /package/dist/{s3-GMPUJ65D.js.map → s3-4OIOCAAT.js.map} +0 -0
- /package/dist/{scaleway-5VM55Y6D.js.map → scaleway-CCWCLUHB.js.map} +0 -0
- /package/dist/{seaweedfs-J3EPUEPE.js.map → seaweedfs-QSWKF2FN.js.map} +0 -0
- /package/dist/{slack-FVBXY7KD.js.map → slack-YPS7PII3.js.map} +0 -0
- /package/dist/{ssh-GCXETJ3Z.js.map → ssh-YFP3SMTJ.js.map} +0 -0
- /package/dist/{supabase-HLWNHBBE.js.map → supabase-6CFTOKGZ.js.map} +0 -0
- /package/dist/{tencent-YDO73XBD.js.map → tencent-IWZZOSQ4.js.map} +0 -0
- /package/dist/{trello-CQ53BQUL.js.map → trello-XYKWZD6P.js.map} +0 -0
- /package/dist/{wasabi-SOZKPMRQ.js.map → wasabi-6Z4DC5S5.js.map} +0 -0
|
@@ -0,0 +1,1095 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadOptionalPeer
|
|
3
|
+
} from "./chunk-E2ISWXLB.js";
|
|
4
|
+
|
|
5
|
+
// src/resource/redis/redis.ts
|
|
6
|
+
import {
|
|
7
|
+
BaseResource,
|
|
8
|
+
PathSpec as PathSpec2,
|
|
9
|
+
REDACTED_SECRET,
|
|
10
|
+
ResourceName as ResourceName21
|
|
11
|
+
} from "@struktoai/mirage-core";
|
|
12
|
+
|
|
13
|
+
// src/commands/builtin/redis/index.ts
|
|
14
|
+
import {
|
|
15
|
+
ResourceName as ResourceName5,
|
|
16
|
+
makeFiletypeCommands,
|
|
17
|
+
makeGenericCommands
|
|
18
|
+
} from "@struktoai/mirage-core";
|
|
19
|
+
|
|
20
|
+
// src/core/redis/read.ts
|
|
21
|
+
import { record, ResourceName } from "@struktoai/mirage-core";
|
|
22
|
+
import { enoent } from "@struktoai/mirage-core";
|
|
23
|
+
|
|
24
|
+
// src/core/redis/utils.ts
|
|
25
|
+
import { norm, parent, gnuBasename } from "@struktoai/mirage-core";
|
|
26
|
+
function nowIso() {
|
|
27
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/core/redis/read.ts
|
|
31
|
+
async function read(accessor, path, _index) {
|
|
32
|
+
const start = performance.now();
|
|
33
|
+
const p = norm(path.stripPrefix);
|
|
34
|
+
const data = await accessor.store.getFile(p);
|
|
35
|
+
if (data === null) {
|
|
36
|
+
throw enoent(path);
|
|
37
|
+
}
|
|
38
|
+
record("read", p, ResourceName.REDIS, data.byteLength, start);
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/core/redis/stat.ts
|
|
43
|
+
import {
|
|
44
|
+
FileStat,
|
|
45
|
+
FileType,
|
|
46
|
+
guessType
|
|
47
|
+
} from "@struktoai/mirage-core";
|
|
48
|
+
import { enoent as enoent2 } from "@struktoai/mirage-core";
|
|
49
|
+
async function stat(accessor, path, _index) {
|
|
50
|
+
const p = norm(path.stripPrefix);
|
|
51
|
+
const store = accessor.store;
|
|
52
|
+
if (await store.hasDir(p)) {
|
|
53
|
+
return new FileStat({
|
|
54
|
+
name: gnuBasename(p),
|
|
55
|
+
modified: await store.getModified(p),
|
|
56
|
+
type: FileType.DIRECTORY
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (await store.hasFile(p)) {
|
|
60
|
+
const size = await store.fileLen(p);
|
|
61
|
+
return new FileStat({
|
|
62
|
+
name: gnuBasename(p),
|
|
63
|
+
size,
|
|
64
|
+
modified: await store.getModified(p),
|
|
65
|
+
type: guessType(p)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
throw enoent2(path);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/core/redis/constants.ts
|
|
72
|
+
var SCOPE_ERROR = 5e4;
|
|
73
|
+
|
|
74
|
+
// src/core/redis/copy.ts
|
|
75
|
+
import { invalidateAfterWrite } from "@struktoai/mirage-core";
|
|
76
|
+
async function copy(accessor, src, dst) {
|
|
77
|
+
const s = norm(src.stripPrefix);
|
|
78
|
+
const d = norm(dst.stripPrefix);
|
|
79
|
+
const store = accessor.store;
|
|
80
|
+
const data = await store.getFile(s);
|
|
81
|
+
if (data === null) {
|
|
82
|
+
throw new Error(`file not found: ${s}`);
|
|
83
|
+
}
|
|
84
|
+
await store.setFile(d, data);
|
|
85
|
+
await store.setModified(d, nowIso());
|
|
86
|
+
await invalidateAfterWrite(dst);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/core/redis/du.ts
|
|
90
|
+
import { rstripSlash } from "@struktoai/mirage-core";
|
|
91
|
+
async function du(accessor, path) {
|
|
92
|
+
const p = norm(path.stripPrefix);
|
|
93
|
+
const store = accessor.store;
|
|
94
|
+
const prefix = rstripSlash(p) + "/";
|
|
95
|
+
let total = 0;
|
|
96
|
+
for (const key of await store.listFiles()) {
|
|
97
|
+
if (key === p || key.startsWith(prefix)) {
|
|
98
|
+
total += await store.fileLen(key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return total;
|
|
102
|
+
}
|
|
103
|
+
async function duAll(accessor, path) {
|
|
104
|
+
const p = norm(path.stripPrefix);
|
|
105
|
+
const store = accessor.store;
|
|
106
|
+
const prefix = rstripSlash(p) + "/";
|
|
107
|
+
const entries = [];
|
|
108
|
+
let total = 0;
|
|
109
|
+
for (const key of await store.listFiles()) {
|
|
110
|
+
if (key === p || key.startsWith(prefix)) {
|
|
111
|
+
const size = await store.fileLen(key);
|
|
112
|
+
entries.push([key, size]);
|
|
113
|
+
total += size;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { entries, total };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/core/redis/exists.ts
|
|
120
|
+
async function exists(accessor, path) {
|
|
121
|
+
const p = norm(path.stripPrefix);
|
|
122
|
+
const store = accessor.store;
|
|
123
|
+
return await store.hasFile(p) || await store.hasDir(p);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/core/redis/find.ts
|
|
127
|
+
import {
|
|
128
|
+
buildTree,
|
|
129
|
+
computeNonemptyDirs,
|
|
130
|
+
emitStartPath,
|
|
131
|
+
keep,
|
|
132
|
+
rstripSlash as rstripSlash2,
|
|
133
|
+
startBasename
|
|
134
|
+
} from "@struktoai/mirage-core";
|
|
135
|
+
async function find(accessor, path, options = {}) {
|
|
136
|
+
const p = norm(path.stripPrefix);
|
|
137
|
+
const startName = startBasename(path.original);
|
|
138
|
+
const store = accessor.store;
|
|
139
|
+
const prefix = rstripSlash2(p) + "/";
|
|
140
|
+
const baseDepth = p === "/" ? 0 : (p.match(/\//g) ?? []).length;
|
|
141
|
+
const results = [];
|
|
142
|
+
const tree = options.tree ?? buildTree({
|
|
143
|
+
name: options.name,
|
|
144
|
+
iname: options.iname,
|
|
145
|
+
pathPattern: options.pathPattern,
|
|
146
|
+
type: options.type,
|
|
147
|
+
nameExclude: options.nameExclude,
|
|
148
|
+
orNames: options.orNames,
|
|
149
|
+
empty: options.empty
|
|
150
|
+
});
|
|
151
|
+
const empty = options.empty === true;
|
|
152
|
+
const allFiles = await store.listFiles();
|
|
153
|
+
const allDirs = await store.listDirs();
|
|
154
|
+
const nonempty = empty ? computeNonemptyDirs([...allFiles, ...[...allDirs].filter((k) => k !== "/")]) : /* @__PURE__ */ new Set();
|
|
155
|
+
const candidates = [];
|
|
156
|
+
if (options.type !== "d") {
|
|
157
|
+
for (const key of allFiles) candidates.push([key, "f"]);
|
|
158
|
+
}
|
|
159
|
+
if (options.type !== "f") {
|
|
160
|
+
for (const key of allDirs) {
|
|
161
|
+
candidates.push([key, "d"]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
let rootKind = null;
|
|
165
|
+
let rootIsEmpty = null;
|
|
166
|
+
let rootSize = null;
|
|
167
|
+
for (const [key, kind] of candidates) {
|
|
168
|
+
if (key !== p && !key.startsWith(prefix)) continue;
|
|
169
|
+
if (key === p) {
|
|
170
|
+
rootKind = kind;
|
|
171
|
+
if (empty) {
|
|
172
|
+
rootIsEmpty = kind === "f" ? await store.fileLen(key) === 0 : !nonempty.has(key);
|
|
173
|
+
}
|
|
174
|
+
if (kind === "f") rootSize = await store.fileLen(key);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const depth = (key.match(/\//g) ?? []).length - baseDepth;
|
|
178
|
+
if (options.maxDepth !== null && options.maxDepth !== void 0 && depth > options.maxDepth)
|
|
179
|
+
continue;
|
|
180
|
+
const basename = key.slice(key.lastIndexOf("/") + 1);
|
|
181
|
+
let isEmpty = null;
|
|
182
|
+
if (empty) {
|
|
183
|
+
isEmpty = kind === "f" ? await store.fileLen(key) === 0 : !nonempty.has(key);
|
|
184
|
+
}
|
|
185
|
+
if (!keep({ key, name: basename, kind, depth, isEmpty }, tree, options.minDepth)) continue;
|
|
186
|
+
if (kind === "f" && (options.minSize !== null && options.minSize !== void 0 || options.maxSize !== null && options.maxSize !== void 0)) {
|
|
187
|
+
const size = await store.fileLen(key);
|
|
188
|
+
if (options.minSize !== null && options.minSize !== void 0 && size < options.minSize)
|
|
189
|
+
continue;
|
|
190
|
+
if (options.maxSize !== null && options.maxSize !== void 0 && size > options.maxSize)
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
results.push(key);
|
|
194
|
+
}
|
|
195
|
+
if (rootKind !== null) {
|
|
196
|
+
emitStartPath(results, p, startName, {
|
|
197
|
+
kind: rootKind,
|
|
198
|
+
isEmpty: rootIsEmpty,
|
|
199
|
+
exists: true,
|
|
200
|
+
tree,
|
|
201
|
+
maxDepth: options.maxDepth,
|
|
202
|
+
minDepth: options.minDepth,
|
|
203
|
+
size: rootSize,
|
|
204
|
+
minSize: options.minSize,
|
|
205
|
+
maxSize: options.maxSize
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
results.sort();
|
|
209
|
+
return results;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/core/redis/mkdir.ts
|
|
213
|
+
import { invalidateAfterWrite as invalidateAfterWrite2 } from "@struktoai/mirage-core";
|
|
214
|
+
import { stripSlash } from "@struktoai/mirage-core";
|
|
215
|
+
async function mkdir(accessor, path, parents = false) {
|
|
216
|
+
const p = norm(path.stripPrefix);
|
|
217
|
+
const store = accessor.store;
|
|
218
|
+
if (parents) {
|
|
219
|
+
const parts = stripSlash(p).split("/");
|
|
220
|
+
let current = "";
|
|
221
|
+
const now = nowIso();
|
|
222
|
+
for (const part of parts) {
|
|
223
|
+
current += `/${part}`;
|
|
224
|
+
await store.addDir(current);
|
|
225
|
+
const mod = await store.getModified(current);
|
|
226
|
+
if (mod === null) {
|
|
227
|
+
await store.setModified(current, now);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const par = parent(p);
|
|
233
|
+
if (par !== "/" && !await store.hasDir(par)) {
|
|
234
|
+
throw new Error(`parent directory does not exist: ${par}`);
|
|
235
|
+
}
|
|
236
|
+
await store.addDir(p);
|
|
237
|
+
await store.setModified(p, nowIso());
|
|
238
|
+
await invalidateAfterWrite2(p);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/core/redis/readdir.ts
|
|
242
|
+
import "@struktoai/mirage-core";
|
|
243
|
+
import { enotdir } from "@struktoai/mirage-core";
|
|
244
|
+
|
|
245
|
+
// src/core/redis/entry.ts
|
|
246
|
+
import { IndexEntry } from "@struktoai/mirage-core";
|
|
247
|
+
var RedisResourceType = Object.freeze({
|
|
248
|
+
FILE: "file",
|
|
249
|
+
FOLDER: "folder"
|
|
250
|
+
});
|
|
251
|
+
var RedisIndexEntry = class _RedisIndexEntry extends IndexEntry {
|
|
252
|
+
static file(path, size = 0) {
|
|
253
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
254
|
+
return new _RedisIndexEntry({
|
|
255
|
+
id: path,
|
|
256
|
+
name,
|
|
257
|
+
resourceType: RedisResourceType.FILE,
|
|
258
|
+
vfsName: name,
|
|
259
|
+
size
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
static folder(path) {
|
|
263
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
264
|
+
return new _RedisIndexEntry({
|
|
265
|
+
id: path,
|
|
266
|
+
name,
|
|
267
|
+
resourceType: RedisResourceType.FOLDER,
|
|
268
|
+
vfsName: name
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// src/core/redis/readdir.ts
|
|
274
|
+
async function readdir(accessor, path, index) {
|
|
275
|
+
const virtual = path.pattern !== null ? path.directory : path.stripPrefix;
|
|
276
|
+
const mountPrefix = path.prefix;
|
|
277
|
+
const virtualKey = mountPrefix + virtual;
|
|
278
|
+
if (index !== void 0) {
|
|
279
|
+
const cached = await index.listDir(virtualKey);
|
|
280
|
+
if (cached.entries !== void 0 && cached.entries !== null) {
|
|
281
|
+
return cached.entries;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const store = accessor.store;
|
|
285
|
+
const p = norm(virtual);
|
|
286
|
+
if (!await store.hasDir(p)) {
|
|
287
|
+
throw enotdir(path);
|
|
288
|
+
}
|
|
289
|
+
const dirPrefix = p === "/" ? "/" : `${p}/`;
|
|
290
|
+
const seen = /* @__PURE__ */ new Set();
|
|
291
|
+
const files = await store.listFiles();
|
|
292
|
+
const dirs = await store.listDirs();
|
|
293
|
+
for (const key of [...files, ...dirs]) {
|
|
294
|
+
if (key === p) continue;
|
|
295
|
+
if (!key.startsWith(dirPrefix)) continue;
|
|
296
|
+
const remainder = key.slice(dirPrefix.length);
|
|
297
|
+
const first = remainder.split("/")[0];
|
|
298
|
+
if (first !== void 0 && first.length > 0) seen.add(dirPrefix + first);
|
|
299
|
+
}
|
|
300
|
+
const sorted = [...seen].sort();
|
|
301
|
+
const virtualEntries = sorted.map((entry) => `${mountPrefix}${entry}`);
|
|
302
|
+
if (index !== void 0) {
|
|
303
|
+
const fileSet = new Set(files);
|
|
304
|
+
const entries = sorted.map((e) => {
|
|
305
|
+
const name = e.slice(e.lastIndexOf("/") + 1);
|
|
306
|
+
return [name, fileSet.has(e) ? RedisIndexEntry.file(e) : RedisIndexEntry.folder(e)];
|
|
307
|
+
});
|
|
308
|
+
await index.setDir(virtualKey, entries);
|
|
309
|
+
}
|
|
310
|
+
return virtualEntries;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// src/core/redis/rename.ts
|
|
314
|
+
import { invalidateAfterUnlink, invalidateAfterWrite as invalidateAfterWrite3 } from "@struktoai/mirage-core";
|
|
315
|
+
import { rstripSlash as rstripSlash3 } from "@struktoai/mirage-core";
|
|
316
|
+
async function rename(accessor, src, dst) {
|
|
317
|
+
const s = norm(src.stripPrefix);
|
|
318
|
+
const d = norm(dst.stripPrefix);
|
|
319
|
+
const now = nowIso();
|
|
320
|
+
const store = accessor.store;
|
|
321
|
+
if (await store.hasFile(s)) {
|
|
322
|
+
const data = await store.getFile(s);
|
|
323
|
+
const mod = await store.getModified(s);
|
|
324
|
+
if (data === null) throw new Error(`file not found: ${s}`);
|
|
325
|
+
await store.delFile(s);
|
|
326
|
+
await store.delModified(s);
|
|
327
|
+
await store.setFile(d, data);
|
|
328
|
+
await store.setModified(d, mod ?? now);
|
|
329
|
+
await invalidateAfterUnlink(s);
|
|
330
|
+
await invalidateAfterWrite3(d);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (await store.hasDir(s)) {
|
|
334
|
+
const mod = await store.getModified(s);
|
|
335
|
+
await store.removeDir(s);
|
|
336
|
+
await store.delModified(s);
|
|
337
|
+
await store.addDir(d);
|
|
338
|
+
await store.setModified(d, mod ?? now);
|
|
339
|
+
const prefix = rstripSlash3(s) + "/";
|
|
340
|
+
const dPrefix = rstripSlash3(d) + "/";
|
|
341
|
+
const files = await store.listFiles();
|
|
342
|
+
for (const key of files) {
|
|
343
|
+
if (key.startsWith(prefix)) {
|
|
344
|
+
const newKey = dPrefix + key.slice(prefix.length);
|
|
345
|
+
const data = await store.getFile(key);
|
|
346
|
+
if (data === null) continue;
|
|
347
|
+
await store.delFile(key);
|
|
348
|
+
await store.setFile(newKey, data);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
await invalidateAfterUnlink(s);
|
|
352
|
+
await invalidateAfterWrite3(d);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
throw new Error(`file not found: ${s}`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/core/redis/rm.ts
|
|
359
|
+
import { invalidateAfterUnlink as invalidateAfterUnlink2, rstripSlash as rstripSlash4 } from "@struktoai/mirage-core";
|
|
360
|
+
async function rmR(accessor, path) {
|
|
361
|
+
const p = norm(path.stripPrefix);
|
|
362
|
+
const store = accessor.store;
|
|
363
|
+
const prefix = rstripSlash4(p) + "/";
|
|
364
|
+
const files = await store.listFiles();
|
|
365
|
+
for (const key of files) {
|
|
366
|
+
if (key === p || key.startsWith(prefix)) {
|
|
367
|
+
await store.delFile(key);
|
|
368
|
+
await store.delModified(key);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const dirs = await store.listDirs();
|
|
372
|
+
for (const key of dirs) {
|
|
373
|
+
if (key === p || key.startsWith(prefix)) {
|
|
374
|
+
await store.removeDir(key);
|
|
375
|
+
await store.delModified(key);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
await invalidateAfterUnlink2(path);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/core/redis/rmdir.ts
|
|
382
|
+
import { invalidateAfterUnlink as invalidateAfterUnlink3, rstripSlash as rstripSlash5 } from "@struktoai/mirage-core";
|
|
383
|
+
async function rmdir(accessor, path) {
|
|
384
|
+
const p = norm(path.stripPrefix);
|
|
385
|
+
const store = accessor.store;
|
|
386
|
+
if (!await store.hasDir(p)) {
|
|
387
|
+
throw new Error(`not a directory: ${p}`);
|
|
388
|
+
}
|
|
389
|
+
const prefix = rstripSlash5(p) + "/";
|
|
390
|
+
const files = await store.listFiles();
|
|
391
|
+
const dirs = await store.listDirs();
|
|
392
|
+
const candidates = [...files, ...dirs];
|
|
393
|
+
for (const k of candidates) {
|
|
394
|
+
if (k !== p && k.startsWith(prefix)) {
|
|
395
|
+
throw new Error(`directory not empty: ${p}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
await store.removeDir(p);
|
|
399
|
+
await invalidateAfterUnlink3(path);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// src/core/redis/stream.ts
|
|
403
|
+
import {
|
|
404
|
+
recordStream,
|
|
405
|
+
ResourceName as ResourceName2
|
|
406
|
+
} from "@struktoai/mirage-core";
|
|
407
|
+
import { enoent as enoent3 } from "@struktoai/mirage-core";
|
|
408
|
+
async function* stream(accessor, path, _index) {
|
|
409
|
+
const p = norm(path.stripPrefix);
|
|
410
|
+
const data = await accessor.store.getFile(p);
|
|
411
|
+
if (data === null) throw enoent3(path);
|
|
412
|
+
const rec = recordStream("read", p, ResourceName2.REDIS);
|
|
413
|
+
if (rec !== null) rec.bytes = data.byteLength;
|
|
414
|
+
yield data;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/core/redis/unlink.ts
|
|
418
|
+
import { invalidateAfterUnlink as invalidateAfterUnlink4 } from "@struktoai/mirage-core";
|
|
419
|
+
async function unlink(accessor, path) {
|
|
420
|
+
const p = norm(path.stripPrefix);
|
|
421
|
+
const store = accessor.store;
|
|
422
|
+
if (!await store.hasFile(p)) {
|
|
423
|
+
throw new Error(`file not found: ${p}`);
|
|
424
|
+
}
|
|
425
|
+
await store.delFile(p);
|
|
426
|
+
await store.delModified(p);
|
|
427
|
+
await invalidateAfterUnlink4(p);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/core/redis/write.ts
|
|
431
|
+
import { ResourceName as ResourceName3, invalidateAfterWrite as invalidateAfterWrite4, record as record2 } from "@struktoai/mirage-core";
|
|
432
|
+
async function writeBytes(accessor, path, data) {
|
|
433
|
+
const start = performance.now();
|
|
434
|
+
const p = norm(path.stripPrefix);
|
|
435
|
+
const par = parent(p);
|
|
436
|
+
const store = accessor.store;
|
|
437
|
+
if (par !== "/" && !await store.hasDir(par)) {
|
|
438
|
+
throw new Error(`parent directory does not exist: ${par}`);
|
|
439
|
+
}
|
|
440
|
+
await store.setFile(p, data);
|
|
441
|
+
await store.setModified(p, nowIso());
|
|
442
|
+
record2("write", p, ResourceName3.REDIS, data.byteLength, start);
|
|
443
|
+
await invalidateAfterWrite4(p);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// src/commands/builtin/redis/ops.ts
|
|
447
|
+
var REDIS_CMD_OPS = {
|
|
448
|
+
readdir,
|
|
449
|
+
readBytes: read,
|
|
450
|
+
readStream: stream,
|
|
451
|
+
stat,
|
|
452
|
+
isMounted: () => true,
|
|
453
|
+
local: true,
|
|
454
|
+
maxGlobMatches: SCOPE_ERROR,
|
|
455
|
+
write: writeBytes,
|
|
456
|
+
exists,
|
|
457
|
+
mkdir,
|
|
458
|
+
unlink,
|
|
459
|
+
rmdir,
|
|
460
|
+
rmR,
|
|
461
|
+
rename,
|
|
462
|
+
copy,
|
|
463
|
+
find,
|
|
464
|
+
duTotal: du,
|
|
465
|
+
duAll: async (accessor, path) => {
|
|
466
|
+
const { entries, total } = await duAll(accessor, path);
|
|
467
|
+
return [entries, total];
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/commands/builtin/redis/sed.ts
|
|
472
|
+
import { ResourceName as ResourceName4, makeSed } from "@struktoai/mirage-core";
|
|
473
|
+
var REDIS_SED = makeSed({
|
|
474
|
+
resource: ResourceName4.REDIS,
|
|
475
|
+
stream: (a, p) => stream(a, p),
|
|
476
|
+
write: (a, p, d) => writeBytes(a, p, d)
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// src/commands/builtin/redis/index.ts
|
|
480
|
+
var REDIS_COMMANDS = [
|
|
481
|
+
...makeFiletypeCommands({
|
|
482
|
+
resource: ResourceName5.REDIS,
|
|
483
|
+
readBytes: read,
|
|
484
|
+
statEntry: stat
|
|
485
|
+
}),
|
|
486
|
+
...makeGenericCommands(ResourceName5.REDIS, REDIS_CMD_OPS),
|
|
487
|
+
...REDIS_SED
|
|
488
|
+
];
|
|
489
|
+
|
|
490
|
+
// src/accessor/redis.ts
|
|
491
|
+
import { Accessor } from "@struktoai/mirage-core";
|
|
492
|
+
var RedisAccessor = class extends Accessor {
|
|
493
|
+
store;
|
|
494
|
+
constructor(store) {
|
|
495
|
+
super();
|
|
496
|
+
this.store = store;
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
// src/core/redis/append.ts
|
|
501
|
+
import { ResourceName as ResourceName6, invalidateAfterWrite as invalidateAfterWrite5, record as record3 } from "@struktoai/mirage-core";
|
|
502
|
+
async function appendBytes(accessor, path, data) {
|
|
503
|
+
const start = performance.now();
|
|
504
|
+
const p = norm(path.stripPrefix);
|
|
505
|
+
const store = accessor.store;
|
|
506
|
+
const existing = await store.getFile(p);
|
|
507
|
+
if (existing !== null) {
|
|
508
|
+
const merged = new Uint8Array(existing.byteLength + data.byteLength);
|
|
509
|
+
merged.set(existing, 0);
|
|
510
|
+
merged.set(data, existing.byteLength);
|
|
511
|
+
await store.setFile(p, merged);
|
|
512
|
+
} else {
|
|
513
|
+
await store.setFile(p, data);
|
|
514
|
+
}
|
|
515
|
+
await store.setModified(p, nowIso());
|
|
516
|
+
record3("append", p, ResourceName6.REDIS, data.byteLength, start);
|
|
517
|
+
await invalidateAfterWrite5(p);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/core/redis/create.ts
|
|
521
|
+
import { invalidateAfterWrite as invalidateAfterWrite6 } from "@struktoai/mirage-core";
|
|
522
|
+
async function create(accessor, path) {
|
|
523
|
+
const p = norm(path.stripPrefix);
|
|
524
|
+
const store = accessor.store;
|
|
525
|
+
await store.setFile(p, new Uint8Array(0));
|
|
526
|
+
await store.setModified(p, nowIso());
|
|
527
|
+
await invalidateAfterWrite6(path);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/core/redis/glob.ts
|
|
531
|
+
import { PathSpec } from "@struktoai/mirage-core";
|
|
532
|
+
import { fnmatch } from "@struktoai/mirage-core";
|
|
533
|
+
import { gnuBasename as gnuBasename2 } from "@struktoai/mirage-core";
|
|
534
|
+
async function resolveGlob(accessor, paths, index) {
|
|
535
|
+
const result = [];
|
|
536
|
+
for (const p of paths) {
|
|
537
|
+
if (p.resolved) {
|
|
538
|
+
result.push(p);
|
|
539
|
+
} else if (p.pattern !== null) {
|
|
540
|
+
const dirSpec = new PathSpec({
|
|
541
|
+
original: p.directory,
|
|
542
|
+
directory: p.directory,
|
|
543
|
+
resolved: true,
|
|
544
|
+
prefix: p.prefix
|
|
545
|
+
});
|
|
546
|
+
const entries = await readdir(accessor, dirSpec, index);
|
|
547
|
+
const matched = [];
|
|
548
|
+
for (const e of entries) {
|
|
549
|
+
if (fnmatch(gnuBasename2(e), p.pattern)) {
|
|
550
|
+
matched.push(
|
|
551
|
+
new PathSpec({
|
|
552
|
+
original: e,
|
|
553
|
+
directory: p.directory,
|
|
554
|
+
resolved: true,
|
|
555
|
+
prefix: p.prefix
|
|
556
|
+
})
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (matched.length > SCOPE_ERROR) matched.length = SCOPE_ERROR;
|
|
561
|
+
result.push(...matched);
|
|
562
|
+
} else {
|
|
563
|
+
result.push(p);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// src/core/redis/truncate.ts
|
|
570
|
+
import { invalidateAfterWrite as invalidateAfterWrite7 } from "@struktoai/mirage-core";
|
|
571
|
+
async function truncate(accessor, path, length) {
|
|
572
|
+
const p = norm(path.stripPrefix);
|
|
573
|
+
const store = accessor.store;
|
|
574
|
+
const existing = await store.getFile(p);
|
|
575
|
+
const data = existing ?? new Uint8Array(0);
|
|
576
|
+
const out = new Uint8Array(length);
|
|
577
|
+
const copyLen = Math.min(data.byteLength, length);
|
|
578
|
+
out.set(data.subarray(0, copyLen), 0);
|
|
579
|
+
await store.setFile(p, out);
|
|
580
|
+
await store.setModified(p, nowIso());
|
|
581
|
+
await invalidateAfterWrite7(p);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/ops/redis/append.ts
|
|
585
|
+
import { ResourceName as ResourceName7 } from "@struktoai/mirage-core";
|
|
586
|
+
var appendOp = {
|
|
587
|
+
name: "append",
|
|
588
|
+
resource: ResourceName7.REDIS,
|
|
589
|
+
filetype: null,
|
|
590
|
+
write: true,
|
|
591
|
+
fn: (accessor, path, args) => {
|
|
592
|
+
const data = args[0];
|
|
593
|
+
if (!(data instanceof Uint8Array)) {
|
|
594
|
+
throw new TypeError("append op requires a Uint8Array as the first arg");
|
|
595
|
+
}
|
|
596
|
+
return appendBytes(accessor, path, data);
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
// src/ops/redis/create.ts
|
|
601
|
+
import { ResourceName as ResourceName8 } from "@struktoai/mirage-core";
|
|
602
|
+
var createOp = {
|
|
603
|
+
name: "create",
|
|
604
|
+
resource: ResourceName8.REDIS,
|
|
605
|
+
filetype: null,
|
|
606
|
+
write: true,
|
|
607
|
+
fn: (accessor, path) => {
|
|
608
|
+
return create(accessor, path);
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
// src/ops/redis/mkdir.ts
|
|
613
|
+
import { ResourceName as ResourceName9 } from "@struktoai/mirage-core";
|
|
614
|
+
var mkdirOp = {
|
|
615
|
+
name: "mkdir",
|
|
616
|
+
resource: ResourceName9.REDIS,
|
|
617
|
+
filetype: null,
|
|
618
|
+
write: true,
|
|
619
|
+
fn: (accessor, path, args) => {
|
|
620
|
+
const parents = args[0];
|
|
621
|
+
return mkdir(accessor, path, parents === true);
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
// src/ops/redis/read.ts
|
|
626
|
+
import { ResourceName as ResourceName10 } from "@struktoai/mirage-core";
|
|
627
|
+
var readOp = {
|
|
628
|
+
name: "read",
|
|
629
|
+
resource: ResourceName10.REDIS,
|
|
630
|
+
filetype: null,
|
|
631
|
+
write: false,
|
|
632
|
+
fn: (accessor, path) => {
|
|
633
|
+
return read(accessor, path);
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
// src/ops/redis/read_feather.ts
|
|
638
|
+
import {
|
|
639
|
+
featherCat,
|
|
640
|
+
ResourceName as ResourceName11
|
|
641
|
+
} from "@struktoai/mirage-core";
|
|
642
|
+
var readFeatherOp = {
|
|
643
|
+
name: "read",
|
|
644
|
+
resource: ResourceName11.REDIS,
|
|
645
|
+
filetype: ".feather",
|
|
646
|
+
write: false,
|
|
647
|
+
fn: async (accessor, path, _args, kwargs) => {
|
|
648
|
+
const raw = await read(accessor, path, kwargs.index);
|
|
649
|
+
return featherCat(raw);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/ops/redis/read_hdf5.ts
|
|
654
|
+
import {
|
|
655
|
+
hdf5Cat,
|
|
656
|
+
ResourceName as ResourceName12
|
|
657
|
+
} from "@struktoai/mirage-core";
|
|
658
|
+
var readHdf5Op = {
|
|
659
|
+
name: "read",
|
|
660
|
+
resource: ResourceName12.REDIS,
|
|
661
|
+
filetype: ".hdf5",
|
|
662
|
+
write: false,
|
|
663
|
+
fn: async (accessor, path, _args, kwargs) => {
|
|
664
|
+
const raw = await read(accessor, path, kwargs.index);
|
|
665
|
+
return hdf5Cat(raw);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// src/ops/redis/read_parquet.ts
|
|
670
|
+
import {
|
|
671
|
+
parquetCat,
|
|
672
|
+
ResourceName as ResourceName13
|
|
673
|
+
} from "@struktoai/mirage-core";
|
|
674
|
+
var readParquetOp = {
|
|
675
|
+
name: "read",
|
|
676
|
+
resource: ResourceName13.REDIS,
|
|
677
|
+
filetype: ".parquet",
|
|
678
|
+
write: false,
|
|
679
|
+
fn: async (accessor, path, _args, kwargs) => {
|
|
680
|
+
const raw = await read(accessor, path, kwargs.index);
|
|
681
|
+
return parquetCat(raw);
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/ops/redis/readdir.ts
|
|
686
|
+
import { ResourceName as ResourceName14 } from "@struktoai/mirage-core";
|
|
687
|
+
var readdirOp = {
|
|
688
|
+
name: "readdir",
|
|
689
|
+
resource: ResourceName14.REDIS,
|
|
690
|
+
filetype: null,
|
|
691
|
+
write: false,
|
|
692
|
+
fn: (accessor, path) => {
|
|
693
|
+
return readdir(accessor, path);
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
// src/ops/redis/rename.ts
|
|
698
|
+
import { ResourceName as ResourceName15 } from "@struktoai/mirage-core";
|
|
699
|
+
var renameOp = {
|
|
700
|
+
name: "rename",
|
|
701
|
+
resource: ResourceName15.REDIS,
|
|
702
|
+
filetype: null,
|
|
703
|
+
write: true,
|
|
704
|
+
fn: (accessor, path, args) => {
|
|
705
|
+
const dst = args[0];
|
|
706
|
+
if (dst === void 0 || dst === null || typeof dst !== "object" || !("original" in dst)) {
|
|
707
|
+
throw new TypeError("rename op requires a PathSpec destination as the first arg");
|
|
708
|
+
}
|
|
709
|
+
return rename(accessor, path, dst);
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// src/ops/redis/rmdir.ts
|
|
714
|
+
import { ResourceName as ResourceName16 } from "@struktoai/mirage-core";
|
|
715
|
+
var rmdirOp = {
|
|
716
|
+
name: "rmdir",
|
|
717
|
+
resource: ResourceName16.REDIS,
|
|
718
|
+
filetype: null,
|
|
719
|
+
write: true,
|
|
720
|
+
fn: (accessor, path) => {
|
|
721
|
+
return rmdir(accessor, path);
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/ops/redis/stat.ts
|
|
726
|
+
import { ResourceName as ResourceName17 } from "@struktoai/mirage-core";
|
|
727
|
+
var statOp = {
|
|
728
|
+
name: "stat",
|
|
729
|
+
resource: ResourceName17.REDIS,
|
|
730
|
+
filetype: null,
|
|
731
|
+
write: false,
|
|
732
|
+
fn: (accessor, path) => {
|
|
733
|
+
return stat(accessor, path);
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
// src/ops/redis/truncate.ts
|
|
738
|
+
import { ResourceName as ResourceName18 } from "@struktoai/mirage-core";
|
|
739
|
+
var truncateOp = {
|
|
740
|
+
name: "truncate",
|
|
741
|
+
resource: ResourceName18.REDIS,
|
|
742
|
+
filetype: null,
|
|
743
|
+
write: true,
|
|
744
|
+
fn: (accessor, path, args) => {
|
|
745
|
+
const length = args[0];
|
|
746
|
+
if (typeof length !== "number") {
|
|
747
|
+
throw new TypeError("truncate op requires a number length as the first arg");
|
|
748
|
+
}
|
|
749
|
+
return truncate(accessor, path, length);
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
// src/ops/redis/unlink.ts
|
|
754
|
+
import { ResourceName as ResourceName19 } from "@struktoai/mirage-core";
|
|
755
|
+
var unlinkOp = {
|
|
756
|
+
name: "unlink",
|
|
757
|
+
resource: ResourceName19.REDIS,
|
|
758
|
+
filetype: null,
|
|
759
|
+
write: true,
|
|
760
|
+
fn: (accessor, path) => {
|
|
761
|
+
return unlink(accessor, path);
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
// src/ops/redis/write.ts
|
|
766
|
+
import { extractWriteData } from "@struktoai/mirage-core";
|
|
767
|
+
import { ResourceName as ResourceName20 } from "@struktoai/mirage-core";
|
|
768
|
+
var writeOp = {
|
|
769
|
+
name: "write",
|
|
770
|
+
resource: ResourceName20.REDIS,
|
|
771
|
+
filetype: null,
|
|
772
|
+
write: true,
|
|
773
|
+
fn: (accessor, path, args) => {
|
|
774
|
+
const data = extractWriteData(args);
|
|
775
|
+
return writeBytes(accessor, path, data);
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// src/ops/redis/index.ts
|
|
780
|
+
var REDIS_OPS = [
|
|
781
|
+
appendOp,
|
|
782
|
+
createOp,
|
|
783
|
+
mkdirOp,
|
|
784
|
+
readOp,
|
|
785
|
+
readFeatherOp,
|
|
786
|
+
readHdf5Op,
|
|
787
|
+
readParquetOp,
|
|
788
|
+
readdirOp,
|
|
789
|
+
renameOp,
|
|
790
|
+
rmdirOp,
|
|
791
|
+
statOp,
|
|
792
|
+
truncateOp,
|
|
793
|
+
unlinkOp,
|
|
794
|
+
writeOp
|
|
795
|
+
];
|
|
796
|
+
|
|
797
|
+
// src/resource/redis/prompt.ts
|
|
798
|
+
var REDIS_PROMPT = `Redis-backed persistent filesystem. Behaves like a standard filesystem.
|
|
799
|
+
Standard commands: ls, cat, head, tail, grep, wc, find, tree, mkdir, touch, cp, mv, rm, tee.`;
|
|
800
|
+
|
|
801
|
+
// src/resource/redis/store.ts
|
|
802
|
+
var RedisStore = class {
|
|
803
|
+
url;
|
|
804
|
+
keyPrefix;
|
|
805
|
+
providedClient;
|
|
806
|
+
clientPromise = null;
|
|
807
|
+
constructor(options = {}) {
|
|
808
|
+
this.url = options.url ?? "redis://localhost:6379/0";
|
|
809
|
+
this.keyPrefix = options.keyPrefix ?? "mirage:fs:";
|
|
810
|
+
this.providedClient = options.client ?? null;
|
|
811
|
+
}
|
|
812
|
+
fk(path) {
|
|
813
|
+
return `${this.keyPrefix}file:${path}`;
|
|
814
|
+
}
|
|
815
|
+
dk() {
|
|
816
|
+
return `${this.keyPrefix}dir`;
|
|
817
|
+
}
|
|
818
|
+
mk(path) {
|
|
819
|
+
return `${this.keyPrefix}modified:${path}`;
|
|
820
|
+
}
|
|
821
|
+
async client() {
|
|
822
|
+
if (this.providedClient !== null) return this.providedClient;
|
|
823
|
+
this.clientPromise ??= (async () => {
|
|
824
|
+
const mod = await loadOptionalPeer(
|
|
825
|
+
() => import("redis"),
|
|
826
|
+
{ feature: "RedisResource / RedisFileCacheStore", packageName: "redis" }
|
|
827
|
+
);
|
|
828
|
+
const c = mod.createClient({
|
|
829
|
+
url: this.url,
|
|
830
|
+
socket: { reconnectStrategy: false }
|
|
831
|
+
});
|
|
832
|
+
await c.connect();
|
|
833
|
+
await c.sAdd(this.dk(), "/");
|
|
834
|
+
return c;
|
|
835
|
+
})();
|
|
836
|
+
return this.clientPromise;
|
|
837
|
+
}
|
|
838
|
+
async getFile(path) {
|
|
839
|
+
const c = await this.client();
|
|
840
|
+
const typed = c;
|
|
841
|
+
const mod = await import("redis");
|
|
842
|
+
const blob = mod.RESP_TYPES.BLOB_STRING;
|
|
843
|
+
const mapping = { [blob]: Buffer };
|
|
844
|
+
const raw = await typed.withTypeMapping(mapping).get(this.fk(path));
|
|
845
|
+
if (raw === null) return null;
|
|
846
|
+
return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
847
|
+
}
|
|
848
|
+
async setFile(path, data) {
|
|
849
|
+
const c = await this.client();
|
|
850
|
+
await c.set(this.fk(path), Buffer.from(data.buffer, data.byteOffset, data.byteLength));
|
|
851
|
+
}
|
|
852
|
+
async delFile(path) {
|
|
853
|
+
const c = await this.client();
|
|
854
|
+
await c.del(this.fk(path));
|
|
855
|
+
}
|
|
856
|
+
async hasFile(path) {
|
|
857
|
+
const c = await this.client();
|
|
858
|
+
return await c.exists(this.fk(path)) > 0;
|
|
859
|
+
}
|
|
860
|
+
async listFiles(prefix = "") {
|
|
861
|
+
const c = await this.client();
|
|
862
|
+
const pattern = `${this.keyPrefix}file:${prefix}*`;
|
|
863
|
+
const strip = `${this.keyPrefix}file:`.length;
|
|
864
|
+
const result = [];
|
|
865
|
+
for await (const k of c.scanIterator({ MATCH: pattern })) {
|
|
866
|
+
const keys = Array.isArray(k) ? k : [k];
|
|
867
|
+
for (const key of keys) result.push(key.slice(strip));
|
|
868
|
+
}
|
|
869
|
+
return result.sort();
|
|
870
|
+
}
|
|
871
|
+
async fileLen(path) {
|
|
872
|
+
const c = await this.client();
|
|
873
|
+
return c.strLen(this.fk(path));
|
|
874
|
+
}
|
|
875
|
+
async getRange(path, start, end) {
|
|
876
|
+
const c = await this.client();
|
|
877
|
+
const typed = c;
|
|
878
|
+
const mod = await import("redis");
|
|
879
|
+
const blob = mod.RESP_TYPES.BLOB_STRING;
|
|
880
|
+
const mapping = { [blob]: Buffer };
|
|
881
|
+
const raw = await typed.withTypeMapping(mapping).getRange(this.fk(path), start, end);
|
|
882
|
+
return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
883
|
+
}
|
|
884
|
+
async hasDir(path) {
|
|
885
|
+
const c = await this.client();
|
|
886
|
+
return await c.sIsMember(this.dk(), path) === 1;
|
|
887
|
+
}
|
|
888
|
+
async addDir(path) {
|
|
889
|
+
const c = await this.client();
|
|
890
|
+
await c.sAdd(this.dk(), path);
|
|
891
|
+
}
|
|
892
|
+
async removeDir(path) {
|
|
893
|
+
const c = await this.client();
|
|
894
|
+
await c.sRem(this.dk(), path);
|
|
895
|
+
}
|
|
896
|
+
async listDirs() {
|
|
897
|
+
const c = await this.client();
|
|
898
|
+
const members = await c.sMembers(this.dk());
|
|
899
|
+
return new Set(members);
|
|
900
|
+
}
|
|
901
|
+
async getModified(path) {
|
|
902
|
+
const c = await this.client();
|
|
903
|
+
return c.get(this.mk(path));
|
|
904
|
+
}
|
|
905
|
+
async setModified(path, ts) {
|
|
906
|
+
const c = await this.client();
|
|
907
|
+
await c.set(this.mk(path), ts);
|
|
908
|
+
}
|
|
909
|
+
async delModified(path) {
|
|
910
|
+
const c = await this.client();
|
|
911
|
+
await c.del(this.mk(path));
|
|
912
|
+
}
|
|
913
|
+
async clear() {
|
|
914
|
+
const c = await this.client();
|
|
915
|
+
for (const pattern of [`${this.keyPrefix}file:*`, `${this.keyPrefix}modified:*`]) {
|
|
916
|
+
const keys = [];
|
|
917
|
+
for await (const k of c.scanIterator({ MATCH: pattern })) {
|
|
918
|
+
if (Array.isArray(k)) keys.push(...k);
|
|
919
|
+
else keys.push(k);
|
|
920
|
+
}
|
|
921
|
+
if (keys.length > 0) await c.del(keys);
|
|
922
|
+
}
|
|
923
|
+
await c.del(this.dk());
|
|
924
|
+
}
|
|
925
|
+
async close() {
|
|
926
|
+
if (this.providedClient !== null) return;
|
|
927
|
+
if (this.clientPromise === null) return;
|
|
928
|
+
const c = await this.clientPromise;
|
|
929
|
+
const typed = c;
|
|
930
|
+
if (typeof typed.destroy === "function") typed.destroy();
|
|
931
|
+
else if (c.isOpen) await c.quit();
|
|
932
|
+
this.clientPromise = null;
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
// src/resource/redis/redis.ts
|
|
937
|
+
var RedisResource = class extends BaseResource {
|
|
938
|
+
kind = ResourceName21.REDIS;
|
|
939
|
+
cachesReads = false;
|
|
940
|
+
indexTtl = 0;
|
|
941
|
+
prompt = REDIS_PROMPT;
|
|
942
|
+
url;
|
|
943
|
+
keyPrefix;
|
|
944
|
+
store;
|
|
945
|
+
accessor;
|
|
946
|
+
opsMap = {
|
|
947
|
+
read_bytes: read,
|
|
948
|
+
write: writeBytes,
|
|
949
|
+
readdir,
|
|
950
|
+
stat,
|
|
951
|
+
unlink,
|
|
952
|
+
rmdir,
|
|
953
|
+
copy,
|
|
954
|
+
rename,
|
|
955
|
+
mkdir,
|
|
956
|
+
read_stream: stream,
|
|
957
|
+
rm_recursive: rmR,
|
|
958
|
+
du_total: du,
|
|
959
|
+
du_all: duAll,
|
|
960
|
+
create,
|
|
961
|
+
truncate,
|
|
962
|
+
exists,
|
|
963
|
+
find_flat: find,
|
|
964
|
+
append: appendBytes
|
|
965
|
+
};
|
|
966
|
+
constructor(options = {}) {
|
|
967
|
+
super();
|
|
968
|
+
this.url = options.url ?? "redis://localhost:6379/0";
|
|
969
|
+
this.keyPrefix = options.keyPrefix ?? "mirage:fs:";
|
|
970
|
+
this.store = new RedisStore({ url: this.url, keyPrefix: this.keyPrefix });
|
|
971
|
+
this.accessor = new RedisAccessor(this.store);
|
|
972
|
+
}
|
|
973
|
+
async open() {
|
|
974
|
+
await this.store.client();
|
|
975
|
+
}
|
|
976
|
+
close() {
|
|
977
|
+
return this.store.close();
|
|
978
|
+
}
|
|
979
|
+
client() {
|
|
980
|
+
return this.store.client();
|
|
981
|
+
}
|
|
982
|
+
module() {
|
|
983
|
+
return import("redis");
|
|
984
|
+
}
|
|
985
|
+
ops() {
|
|
986
|
+
return REDIS_OPS;
|
|
987
|
+
}
|
|
988
|
+
commands() {
|
|
989
|
+
return REDIS_COMMANDS;
|
|
990
|
+
}
|
|
991
|
+
streamPath(p) {
|
|
992
|
+
return stream(this.accessor, p);
|
|
993
|
+
}
|
|
994
|
+
readFile(p) {
|
|
995
|
+
return read(this.accessor, p);
|
|
996
|
+
}
|
|
997
|
+
writeFile(p, data) {
|
|
998
|
+
return writeBytes(this.accessor, p, data);
|
|
999
|
+
}
|
|
1000
|
+
appendFile(p, data) {
|
|
1001
|
+
return appendBytes(this.accessor, p, data);
|
|
1002
|
+
}
|
|
1003
|
+
readdir(p) {
|
|
1004
|
+
return readdir(this.accessor, p, this.index);
|
|
1005
|
+
}
|
|
1006
|
+
stat(p) {
|
|
1007
|
+
return stat(this.accessor, p);
|
|
1008
|
+
}
|
|
1009
|
+
exists(p) {
|
|
1010
|
+
return exists(this.accessor, p);
|
|
1011
|
+
}
|
|
1012
|
+
mkdir(p, options) {
|
|
1013
|
+
return mkdir(this.accessor, p, options?.recursive === true);
|
|
1014
|
+
}
|
|
1015
|
+
rmdir(p) {
|
|
1016
|
+
return rmdir(this.accessor, p);
|
|
1017
|
+
}
|
|
1018
|
+
unlink(p) {
|
|
1019
|
+
return unlink(this.accessor, p);
|
|
1020
|
+
}
|
|
1021
|
+
rename(src, dst) {
|
|
1022
|
+
return rename(this.accessor, src, dst);
|
|
1023
|
+
}
|
|
1024
|
+
truncate(p, length) {
|
|
1025
|
+
return truncate(this.accessor, p, length);
|
|
1026
|
+
}
|
|
1027
|
+
copy(src, dst) {
|
|
1028
|
+
return copy(this.accessor, src, dst);
|
|
1029
|
+
}
|
|
1030
|
+
rmR(p) {
|
|
1031
|
+
return rmR(this.accessor, p);
|
|
1032
|
+
}
|
|
1033
|
+
du(p) {
|
|
1034
|
+
return du(this.accessor, p);
|
|
1035
|
+
}
|
|
1036
|
+
find(p, options = {}) {
|
|
1037
|
+
return find(this.accessor, p, options);
|
|
1038
|
+
}
|
|
1039
|
+
glob(paths, prefix = "") {
|
|
1040
|
+
const effective = prefix ? paths.map(
|
|
1041
|
+
(p) => p.prefix ? p : new PathSpec2({
|
|
1042
|
+
original: p.original,
|
|
1043
|
+
directory: p.directory,
|
|
1044
|
+
...p.pattern !== null ? { pattern: p.pattern } : {},
|
|
1045
|
+
resolved: p.resolved,
|
|
1046
|
+
prefix
|
|
1047
|
+
})
|
|
1048
|
+
) : paths;
|
|
1049
|
+
return resolveGlob(this.accessor, effective, this.index);
|
|
1050
|
+
}
|
|
1051
|
+
async getState() {
|
|
1052
|
+
const files = {};
|
|
1053
|
+
for (const key of await this.store.listFiles()) {
|
|
1054
|
+
const data = await this.store.getFile(key);
|
|
1055
|
+
if (data !== null) files[key] = data;
|
|
1056
|
+
}
|
|
1057
|
+
const dirs = [...await this.store.listDirs()].sort();
|
|
1058
|
+
return {
|
|
1059
|
+
type: this.kind,
|
|
1060
|
+
config: {
|
|
1061
|
+
url: REDACTED_SECRET,
|
|
1062
|
+
keyPrefix: this.keyPrefix
|
|
1063
|
+
},
|
|
1064
|
+
keyPrefix: this.keyPrefix,
|
|
1065
|
+
files,
|
|
1066
|
+
dirs
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
async loadState(state) {
|
|
1070
|
+
const c = await this.store.client();
|
|
1071
|
+
const pipe = c.multi();
|
|
1072
|
+
const dirKey = `${this.keyPrefix}dir`;
|
|
1073
|
+
for (const [path, data] of Object.entries(state.files)) {
|
|
1074
|
+
pipe.set(
|
|
1075
|
+
`${this.keyPrefix}file:${path}`,
|
|
1076
|
+
Buffer.from(data.buffer, data.byteOffset, data.byteLength)
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
for (const dir of state.dirs) {
|
|
1080
|
+
pipe.sAdd(dirKey, dir);
|
|
1081
|
+
}
|
|
1082
|
+
await pipe.exec();
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
export {
|
|
1087
|
+
stat,
|
|
1088
|
+
REDIS_COMMANDS,
|
|
1089
|
+
RedisAccessor,
|
|
1090
|
+
REDIS_OPS,
|
|
1091
|
+
REDIS_PROMPT,
|
|
1092
|
+
RedisStore,
|
|
1093
|
+
RedisResource
|
|
1094
|
+
};
|
|
1095
|
+
//# sourceMappingURL=chunk-IDYHQQOH.js.map
|