@spacelr/sdk 0.5.0 → 0.5.1

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.mjs CHANGED
@@ -1784,6 +1784,144 @@ var StorageModule = class {
1784
1784
  }
1785
1785
  };
1786
1786
 
1787
+ // libs/sdk/src/modules/timeline.errors.ts
1788
+ var TimelineError = class extends SpacelrError {
1789
+ constructor(message, opts = {}) {
1790
+ super(message, opts.code ?? "TIMELINE_ERROR", opts.statusCode);
1791
+ this.name = "TimelineError";
1792
+ }
1793
+ };
1794
+ var CursorInvalidError = class extends TimelineError {
1795
+ constructor(message, opts = {}) {
1796
+ super(message, { statusCode: opts.statusCode ?? 400, code: opts.code ?? "CURSOR_INVALID" });
1797
+ this.name = "CursorInvalidError";
1798
+ }
1799
+ };
1800
+ var ValidationError = class extends TimelineError {
1801
+ constructor(message, opts = {}) {
1802
+ super(message, { statusCode: opts.statusCode ?? 400, code: opts.code ?? "BAD_REQUEST" });
1803
+ this.name = "ValidationError";
1804
+ }
1805
+ };
1806
+ var ForbiddenError = class extends TimelineError {
1807
+ constructor(message, opts = {}) {
1808
+ super(message, { statusCode: opts.statusCode ?? 403, code: opts.code ?? "FORBIDDEN" });
1809
+ this.name = "ForbiddenError";
1810
+ }
1811
+ };
1812
+ var NotFoundError = class extends TimelineError {
1813
+ constructor(message, opts = {}) {
1814
+ super(message, { statusCode: opts.statusCode ?? 404, code: opts.code ?? "NOT_FOUND" });
1815
+ this.name = "NotFoundError";
1816
+ }
1817
+ };
1818
+ var ServerConfigError = class extends TimelineError {
1819
+ constructor(message, opts = {}) {
1820
+ super(message, { statusCode: opts.statusCode ?? 500, code: opts.code ?? "CONFIG_INVALID" });
1821
+ this.name = "ServerConfigError";
1822
+ }
1823
+ };
1824
+ var TimeoutError = class extends TimelineError {
1825
+ constructor(message, opts = {}) {
1826
+ super(message, { statusCode: opts.statusCode ?? 504, code: opts.code ?? "TIMEOUT" });
1827
+ this.name = "TimeoutError";
1828
+ }
1829
+ };
1830
+ function mapTimelineError(statusCode, body) {
1831
+ const code = body?.code;
1832
+ const message = body?.message ?? `Timeline request failed with HTTP ${statusCode}`;
1833
+ if (statusCode === 400) {
1834
+ if (code === "CURSOR_INVALID") {
1835
+ return new CursorInvalidError(message, { statusCode, code });
1836
+ }
1837
+ return new ValidationError(message, { statusCode, code });
1838
+ }
1839
+ if (statusCode === 403) {
1840
+ return new ForbiddenError(message, { statusCode, code });
1841
+ }
1842
+ if (statusCode === 404) {
1843
+ return new NotFoundError(message, { statusCode, code });
1844
+ }
1845
+ if (statusCode === 500) {
1846
+ return new ServerConfigError(message, { statusCode, code });
1847
+ }
1848
+ if (statusCode === 504) {
1849
+ return new TimeoutError(message, { statusCode, code });
1850
+ }
1851
+ return new TimelineError(message, { statusCode, code });
1852
+ }
1853
+
1854
+ // libs/sdk/src/modules/timeline.module.ts
1855
+ var TimelineModule = class {
1856
+ constructor(http) {
1857
+ this.http = http;
1858
+ }
1859
+ async query(opts) {
1860
+ const body = {
1861
+ collection: opts.collection,
1862
+ partitionValue: opts.partitionValue
1863
+ };
1864
+ if (opts.where !== void 0) body["where"] = opts.where;
1865
+ if (opts.orderBy !== void 0) body["orderBy"] = opts.orderBy;
1866
+ if (opts.limit !== void 0) body["limit"] = opts.limit;
1867
+ if (opts.cursor !== void 0) body["cursor"] = opts.cursor;
1868
+ let raw;
1869
+ try {
1870
+ raw = await this.http.request({
1871
+ method: "POST",
1872
+ path: "/db/timeline",
1873
+ body,
1874
+ authenticated: true
1875
+ });
1876
+ } catch (err) {
1877
+ throw this.translateError(err);
1878
+ }
1879
+ if (!isTimelineQueryResponse(raw)) {
1880
+ throw new TimelineError(
1881
+ "Timeline gateway returned a response shape the SDK does not recognise",
1882
+ { statusCode: 500, code: "INVALID_RESPONSE_SHAPE" }
1883
+ );
1884
+ }
1885
+ return raw;
1886
+ }
1887
+ translateError(err) {
1888
+ if (err instanceof SpacelrTimeoutError) {
1889
+ return new TimeoutError(err.message, { statusCode: 504, code: "TIMEOUT" });
1890
+ }
1891
+ if (err instanceof SpacelrAuthError) {
1892
+ if (err.statusCode === 403) {
1893
+ return new ForbiddenError(err.message, { statusCode: 403, code: err.code ?? "FORBIDDEN" });
1894
+ }
1895
+ return err;
1896
+ }
1897
+ if (err instanceof SpacelrNetworkError) {
1898
+ return err;
1899
+ }
1900
+ if (err instanceof SpacelrError) {
1901
+ return mapTimelineError(err.statusCode ?? 0, { code: err.code, message: err.message });
1902
+ }
1903
+ return err;
1904
+ }
1905
+ };
1906
+ function isTimelineQueryResponse(value) {
1907
+ if (typeof value !== "object" || value === null) return false;
1908
+ const v = value;
1909
+ if (!Array.isArray(v["items"])) return false;
1910
+ if (v["nextCursor"] !== null && typeof v["nextCursor"] !== "string") return false;
1911
+ if (!isTimelineSourceStats(v["sourceStats"])) return false;
1912
+ return true;
1913
+ }
1914
+ function isTimelineSourceStats(value) {
1915
+ if (typeof value !== "object" || value === null) return false;
1916
+ const v = value;
1917
+ if (typeof v["hot"] !== "number") return false;
1918
+ if (typeof v["cold"] !== "number") return false;
1919
+ if (v["segmentsScanned"] !== void 0 && typeof v["segmentsScanned"] !== "number") {
1920
+ return false;
1921
+ }
1922
+ return true;
1923
+ }
1924
+
1787
1925
  // libs/sdk/src/modules/database.module.ts
1788
1926
  var Paginator = class {
1789
1927
  constructor(http, basePath, opts) {
@@ -1967,6 +2105,16 @@ var CollectionRef = class {
1967
2105
  authenticated: true
1968
2106
  });
1969
2107
  }
2108
+ /**
2109
+ * Query the collection's **hot tier** (live MongoDB).
2110
+ *
2111
+ * **Cold-tier note:** if the collection has cold-tier archival enabled, aged
2112
+ * documents are moved to object storage and purged from the hot tier — they
2113
+ * will NOT appear in `find()` results (nor `findById`, `count`, `search`,
2114
+ * `paginate`, which are all hot-tier only). To read archived history, use
2115
+ * {@link TimelineModule.query} via `db.timeline.query(...)`, which transparently
2116
+ * merges hot and cold results for a partition.
2117
+ */
1970
2118
  find(filter) {
1971
2119
  return new QueryBuilder(this.http, this.basePath, filter);
1972
2120
  }
@@ -2001,6 +2149,9 @@ var CollectionRef = class {
2001
2149
  *
2002
2150
  * Limits: `query` 1–200 chars, `fields` 1–10 entries (each matching
2003
2151
  * `/^[a-zA-Z0-9_.]+$/`, max 64 chars), `limit` max 100.
2152
+ *
2153
+ * **Cold-tier note:** searches the hot tier only; archived documents are not
2154
+ * included. See {@link CollectionRef.find} and `db.timeline.query(...)`.
2004
2155
  */
2005
2156
  async search(opts) {
2006
2157
  return this.http.request({
@@ -2010,6 +2161,13 @@ var CollectionRef = class {
2010
2161
  authenticated: true
2011
2162
  });
2012
2163
  }
2164
+ /**
2165
+ * Fetch a single document by `_id` from the **hot tier**.
2166
+ *
2167
+ * **Cold-tier note:** returns null/throws for documents that have been
2168
+ * archived and purged from the hot tier. Archived history is reachable only
2169
+ * via `db.timeline.query(...)`. See {@link CollectionRef.find}.
2170
+ */
2013
2171
  async findById(id, options) {
2014
2172
  const query = {};
2015
2173
  if (options?.populate?.length) {
@@ -2039,6 +2197,13 @@ var CollectionRef = class {
2039
2197
  authenticated: true
2040
2198
  });
2041
2199
  }
2200
+ /**
2201
+ * Count documents in the **hot tier** matching `filter`.
2202
+ *
2203
+ * **Cold-tier note:** counts hot-tier documents only — archived/purged
2204
+ * documents are not included, so this is not a total-history count. See
2205
+ * {@link CollectionRef.find} and `db.timeline.query(...)`.
2206
+ */
2042
2207
  async count(filter) {
2043
2208
  const result = await this.http.request({
2044
2209
  method: "POST",
@@ -2474,6 +2639,7 @@ var DatabaseModule = class {
2474
2639
  this.http = http;
2475
2640
  this.projectId = projectId;
2476
2641
  this.realtime = realtime ?? null;
2642
+ this.timeline = new TimelineModule(http);
2477
2643
  }
2478
2644
  collection(name) {
2479
2645
  return new CollectionRef(this.http, this.realtime, this.projectId, name);
@@ -2783,9 +2949,13 @@ function createClient(config) {
2783
2949
  export {
2784
2950
  BrowserTokenStorage,
2785
2951
  CodeChallengeMethod,
2952
+ CursorInvalidError,
2786
2953
  FileVisibility,
2954
+ ForbiddenError,
2787
2955
  GrantType,
2788
2956
  MemoryTokenStorage,
2957
+ NotFoundError,
2958
+ ServerConfigError,
2789
2959
  SharePermission,
2790
2960
  SpacelrAuthError,
2791
2961
  SpacelrEmailVerificationRequiredError,
@@ -2794,6 +2964,10 @@ export {
2794
2964
  SpacelrSearchFilterRequiredError,
2795
2965
  SpacelrTimeoutError,
2796
2966
  SpacelrTwoFactorRequiredError,
2967
+ TimelineError,
2968
+ TimelineModule,
2969
+ TimeoutError,
2970
+ ValidationError,
2797
2971
  createClient,
2798
2972
  generatePKCEChallenge,
2799
2973
  localStorageCursorStorage,