tensorlake 0.5.85 → 0.5.89

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/dist/index.cjs CHANGED
@@ -35,7 +35,7 @@ var SDK_VERSION, API_URL, API_KEY, NAMESPACE, SANDBOX_PROXY_URL, DEFAULT_HTTP_TI
35
35
  var init_defaults = __esm({
36
36
  "src/defaults.ts"() {
37
37
  "use strict";
38
- SDK_VERSION = "0.5.85";
38
+ SDK_VERSION = "0.5.89";
39
39
  API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
40
40
  API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
41
41
  NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -6576,8 +6576,9 @@ function fileEntryFromWire(entry, dirPath) {
6576
6576
  return {
6577
6577
  name: entry.name,
6578
6578
  path: prefix ? `${prefix}/${entry.name}` : entry.name,
6579
- oid: entry.oid ?? "",
6580
- mode,
6579
+ contentId: entry.oid ?? "",
6580
+ kind: mode === GIT_MODE_DIR ? "directory" : mode === GIT_MODE_SYMLINK ? "symlink" : "file",
6581
+ executable: mode === 33261,
6581
6582
  size: entry.size ?? null,
6582
6583
  isDir: mode === GIT_MODE_DIR,
6583
6584
  isSymlink: mode === GIT_MODE_SYMLINK
@@ -6831,6 +6832,26 @@ var FilesystemClient = class {
6831
6832
  created.default_branch || "main"
6832
6833
  );
6833
6834
  }
6835
+ /**
6836
+ * Fork a filesystem at its live head or an explicit retained snapshot.
6837
+ * The server shares immutable content and publishes only metadata.
6838
+ */
6839
+ async fork(name, baseFilesystem, snapshot) {
6840
+ if (!name || !baseFilesystem) {
6841
+ throw new FilesystemError(
6842
+ "fork and base filesystem names must not be empty"
6843
+ );
6844
+ }
6845
+ await callNative2(
6846
+ () => this.native.forkFilesystem(
6847
+ name,
6848
+ baseFilesystem,
6849
+ snapshot ?? null
6850
+ ),
6851
+ new FilesystemNotFoundError(baseFilesystem)
6852
+ );
6853
+ return new Filesystem(this, this.native, this.cli, name, "main");
6854
+ }
6834
6855
  /** Return a handle to an existing filesystem (verifies it exists). */
6835
6856
  async get(name) {
6836
6857
  const traced = await callNative2(
@@ -6856,7 +6877,6 @@ var FilesystemClient = class {
6856
6877
  return (page.repos ?? []).map((repo) => ({
6857
6878
  name: String(repo.name ?? ""),
6858
6879
  fullName: String(repo.full_name ?? ""),
6859
- defaultBranch: String(repo.default_branch ?? "main"),
6860
6880
  status: String(repo.status ?? ""),
6861
6881
  kind: String(repo.kind ?? FILESYSTEM_REPO_KIND)
6862
6882
  }));
@@ -6936,13 +6956,92 @@ var Filesystem = class {
6936
6956
  content: toBuffer(data)
6937
6957
  }));
6938
6958
  const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
6959
+ return await this.publishChanges(
6960
+ writes,
6961
+ deletes,
6962
+ [],
6963
+ [],
6964
+ resolvedMessage
6965
+ );
6966
+ }
6967
+ /**
6968
+ * Stream one local file directly to object storage in bounded parts.
6969
+ * This is the memory-bounded API for multi-GiB files.
6970
+ */
6971
+ async writeFileFromPath(path2, localPath, message) {
6972
+ return await this.writeFilesFromPaths(
6973
+ /* @__PURE__ */ new Map([[path2, localPath]]),
6974
+ message
6975
+ );
6976
+ }
6977
+ /**
6978
+ * Atomically publish local files without loading their complete payloads
6979
+ * into JavaScript or Rust memory.
6980
+ */
6981
+ async writeFilesFromPaths(files, message) {
6982
+ const entries = files instanceof Map ? [...files.entries()] : Object.entries(files);
6983
+ if (entries.length === 0) {
6984
+ throw new FilesystemError("nothing to write: no local files given");
6985
+ }
6986
+ const writes = entries.map(([path2, localPath]) => ({ path: path2, localPath }));
6987
+ const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
6988
+ const branch = await this.branch();
6989
+ const traced = await callNative2(
6990
+ () => this.native.pushFilesystemPaths(
6991
+ this.name,
6992
+ writes,
6993
+ resolvedMessage,
6994
+ branch,
6995
+ (0, import_node_crypto2.randomBytes)(16).toString("hex")
6996
+ ),
6997
+ new FilesystemNotFoundError(this.name)
6998
+ );
6999
+ const report = JSON.parse(traced.json);
7000
+ const versionId = String(report.version_id ?? "");
7001
+ const previousVersionId = report.previous_version_id == null ? null : String(report.previous_version_id);
7002
+ return {
7003
+ versionId,
7004
+ previousVersionId,
7005
+ created: previousVersionId !== versionId,
7006
+ message: resolvedMessage
7007
+ };
7008
+ }
7009
+ /**
7010
+ * Move a file or directory without downloading or re-uploading its bytes.
7011
+ * The source removal and destination creation publish as one atomic snapshot.
7012
+ */
7013
+ async moveFile(from, to, message) {
7014
+ return await this.publishChanges(
7015
+ [],
7016
+ [],
7017
+ [{ from, to }],
7018
+ [],
7019
+ message || `move ${from} to ${to} via SDK`
7020
+ );
7021
+ }
7022
+ /**
7023
+ * Copy a file or directory by reusing immutable content references. No
7024
+ * payload bytes traverse the client, API server, or object store.
7025
+ */
7026
+ async copyFile(from, to, message) {
7027
+ return await this.publishChanges(
7028
+ [],
7029
+ [],
7030
+ [],
7031
+ [{ from, to }],
7032
+ message || `copy ${from} to ${to} via SDK`
7033
+ );
7034
+ }
7035
+ async publishChanges(writes, deletes, moves, copies, message) {
6939
7036
  const branch = await this.branch();
6940
7037
  const traced = await callNative2(
6941
7038
  () => this.native.pushFilesystemFiles(
6942
7039
  this.name,
6943
7040
  writes,
6944
7041
  deletes,
6945
- resolvedMessage,
7042
+ moves,
7043
+ copies,
7044
+ message,
6946
7045
  branch,
6947
7046
  // One key per logical write: a retried submit reattaches to the
6948
7047
  // same durable commit job instead of double-committing.
@@ -6951,16 +7050,16 @@ var Filesystem = class {
6951
7050
  new FilesystemNotFoundError(this.name)
6952
7051
  );
6953
7052
  const report = JSON.parse(traced.json);
7053
+ const versionId = String(report.version_id ?? "");
7054
+ const previousVersionId = report.previous_version_id == null ? null : String(report.previous_version_id);
6954
7055
  return {
6955
- commit: String(report.commit ?? ""),
6956
- tree: String(report.tree ?? ""),
6957
- refName: String(report.ref_name ?? ""),
6958
- parent: null,
6959
- created: report.created === void 0 ? true : Boolean(report.created),
6960
- message: resolvedMessage
7056
+ versionId,
7057
+ previousVersionId,
7058
+ created: previousVersionId !== versionId,
7059
+ message
6961
7060
  };
6962
7061
  }
6963
- /** Delete one file. Returns the snapshot the deletion produced. */
7062
+ /** Delete one file. Returns the durable version the deletion produced. */
6964
7063
  async deleteFile(path2, message) {
6965
7064
  return await this.writeFiles(
6966
7065
  /* @__PURE__ */ new Map(),
@@ -6971,40 +7070,90 @@ var Filesystem = class {
6971
7070
  /**
6972
7071
  * Return the filesystem's current version as a snapshot.
6973
7072
  *
6974
- * Writes already create snapshots implicitly; this pins the current head
6975
- * without changing any content.
7073
+ * Writes publish durable live versions. This retains the current head
7074
+ * permanently in one metadata-only server operation without changing or
7075
+ * copying any content.
6976
7076
  */
6977
- async snapshot(message = "") {
6978
- const status = await this.status();
6979
- if (!status.headCommit) {
6980
- throw new FilesystemError(
6981
- `filesystem ${this.name} is empty: write files first`
6982
- );
6983
- }
7077
+ async snapshot(message = "snapshot via SDK") {
7078
+ const resolvedMessage = message || "snapshot via SDK";
7079
+ const traced = await callNative2(
7080
+ () => this.native.retainFilesystemSnapshot(
7081
+ this.name,
7082
+ resolvedMessage,
7083
+ (0, import_node_crypto2.randomBytes)(16).toString("hex")
7084
+ ),
7085
+ new FilesystemNotFoundError(this.name)
7086
+ );
7087
+ const retained = JSON.parse(traced.json);
6984
7088
  return {
6985
- commit: status.headCommit,
6986
- tree: "",
6987
- refName: `refs/heads/${status.defaultBranch}`,
6988
- parent: null,
6989
- created: false,
6990
- message
7089
+ id: String(retained.snapshot_id ?? ""),
7090
+ message: retained.message || resolvedMessage
6991
7091
  };
6992
7092
  }
7093
+ /** List explicitly retained snapshots without reading filesystem contents. */
7094
+ async listSnapshots() {
7095
+ const traced = await callNative2(
7096
+ () => this.native.listFilesystemSnapshots(this.name),
7097
+ new FilesystemNotFoundError(this.name)
7098
+ );
7099
+ const payload = JSON.parse(traced.json);
7100
+ return (payload.snapshots ?? []).map((snapshot) => ({
7101
+ id: String(snapshot.snapshot_id ?? ""),
7102
+ createdAt: new Date(Number(snapshot.created_at_ms ?? 0)),
7103
+ message: String(snapshot.message ?? "")
7104
+ }));
7105
+ }
7106
+ /** Delete one permanent retention point; shared/head-reachable bytes remain. */
7107
+ async deleteSnapshot(snapshot) {
7108
+ await callNative2(
7109
+ () => this.native.deleteFilesystemSnapshot(this.name, snapshot),
7110
+ new FilesystemNotFoundError(this.name)
7111
+ );
7112
+ }
6993
7113
  // -- reads --------------------------------------------------------------------
6994
7114
  /**
6995
- * Read a file's bytes at `version` (branch, ref, or snapshot commit;
6996
- * defaults to the filesystem's default branch).
7115
+ * Read a file's bytes at `version` (the current `main` head or a retained
7116
+ * snapshot id; defaults to the filesystem's current head).
6997
7117
  */
6998
7118
  async readFile(path2, version) {
7119
+ return (await this.readFileWithMetadata(path2, { version })).data;
7120
+ }
7121
+ /**
7122
+ * Read bytes and immutable metadata in one request. A range is executed by
7123
+ * Artifact Storage, so callers never download the unrequested remainder.
7124
+ */
7125
+ async readFileWithMetadata(path2, options = {}) {
6999
7126
  if (trimSlashes(path2) === "") {
7000
7127
  throw new FilesystemError("file path must not be empty");
7001
7128
  }
7002
- const resolvedVersion = version || await this.branch();
7129
+ const range = options.range;
7130
+ if (range !== void 0 && (!Number.isSafeInteger(range.offset) || range.offset < 0 || !Number.isSafeInteger(range.length) || range.length <= 0)) {
7131
+ throw new FilesystemError(
7132
+ "range requires a non-negative integer offset and positive integer length"
7133
+ );
7134
+ }
7135
+ const resolvedVersion = options.version || await this.branch();
7003
7136
  const traced = await callNative2(
7004
- () => this.native.readFilesystemFile(this.name, path2, resolvedVersion),
7137
+ () => this.native.readFilesystemFile(
7138
+ this.name,
7139
+ path2,
7140
+ resolvedVersion,
7141
+ range?.offset,
7142
+ range?.length
7143
+ ),
7005
7144
  new FileNotFoundInFilesystemError(this.name, path2)
7006
7145
  );
7007
- return new Uint8Array(traced.data);
7146
+ const fullSize = traced.fullSize;
7147
+ if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
7148
+ throw new FilesystemError(
7149
+ "filesystem read response omitted content identity or total size"
7150
+ );
7151
+ }
7152
+ return {
7153
+ data: new Uint8Array(traced.data),
7154
+ contentId: traced.contentId,
7155
+ size: fullSize
7156
+ };
7008
7157
  }
7009
7158
  /** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
7010
7159
  async readText(path2, version) {
@@ -7023,7 +7172,7 @@ var Filesystem = class {
7023
7172
  return (page.entries ?? []).map((entry) => fileEntryFromWire(entry, dirPath));
7024
7173
  }
7025
7174
  // -- status -------------------------------------------------------------------
7026
- /** Remote status: identity plus the current head snapshot. */
7175
+ /** Remote status: identity plus the current native version. */
7027
7176
  async status() {
7028
7177
  const metaTraced = await callNative2(
7029
7178
  () => this.native.filesystemMeta(this.name),
@@ -7032,14 +7181,14 @@ var Filesystem = class {
7032
7181
  const meta = JSON.parse(metaTraced.json);
7033
7182
  const defaultBranch = String(meta.default_branch || "main");
7034
7183
  this.defaultBranch = defaultBranch;
7035
- let headCommit = null;
7184
+ let versionId = null;
7036
7185
  let generation = null;
7037
7186
  try {
7038
7187
  const refTraced = await callNative2(
7039
7188
  () => this.native.filesystemRefStatus(this.name, defaultBranch)
7040
7189
  );
7041
7190
  const ref = JSON.parse(refTraced.json);
7042
- headCommit = ref.resolved_commit || ref.oid || null;
7191
+ versionId = ref.resolved_commit || ref.oid || null;
7043
7192
  generation = typeof ref.generation === "number" ? ref.generation : null;
7044
7193
  } catch (error) {
7045
7194
  if (!(error instanceof FilesystemAPIError) || error.statusCode !== 404) {
@@ -7049,8 +7198,7 @@ var Filesystem = class {
7049
7198
  return {
7050
7199
  name: this.name,
7051
7200
  status: String(meta.status ?? ""),
7052
- defaultBranch,
7053
- headCommit,
7201
+ versionId,
7054
7202
  generation
7055
7203
  };
7056
7204
  }