mneme-sdk 0.0.1 → 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/dist/index.cjs CHANGED
@@ -74,6 +74,24 @@ function randomNonce() {
74
74
  }
75
75
 
76
76
  // src/client.ts
77
+ async function toUint8Array(input) {
78
+ if (input instanceof Uint8Array) return input;
79
+ if (input instanceof ArrayBuffer) return new Uint8Array(input);
80
+ if (typeof Blob !== "undefined" && input instanceof Blob) {
81
+ return new Uint8Array(await input.arrayBuffer());
82
+ }
83
+ if (typeof input === "string") return new TextEncoder().encode(input);
84
+ throw new Error("unsupported file type for storage.upload");
85
+ }
86
+ function uint8ToBase64(bytes) {
87
+ const CHUNK = 32768;
88
+ const parts = [];
89
+ for (let i = 0; i < bytes.byteLength; i += CHUNK) {
90
+ parts.push(String.fromCharCode(...bytes.subarray(i, i + CHUNK)));
91
+ }
92
+ if (typeof btoa !== "undefined") return btoa(parts.join(""));
93
+ return Buffer.from(parts.join(""), "binary").toString("base64");
94
+ }
77
95
  var MnemeError = class extends Error {
78
96
  constructor(status, message) {
79
97
  super(message);
@@ -122,6 +140,50 @@ var Mneme = class {
122
140
  from(table) {
123
141
  return new Collection(this, table);
124
142
  }
143
+ // ─── Storage (Cloudflare R2 backend, $MNEME burn quota) ──────────────────
144
+ storage = {
145
+ upload: async (args) => {
146
+ const bytes = await toUint8Array(args.file);
147
+ const content_base64 = uint8ToBase64(bytes);
148
+ return this.request("POST", "/v1/storage/upload", {
149
+ key: args.key,
150
+ visibility: args.visibility ?? "private",
151
+ content_type: args.contentType ?? "application/octet-stream",
152
+ content_base64
153
+ });
154
+ },
155
+ list: (args) => {
156
+ const q = new URLSearchParams();
157
+ if (args?.visibility) q.set("visibility", args.visibility);
158
+ if (args?.prefix) q.set("prefix", args.prefix);
159
+ return this.request("GET", `/v1/storage/list${q.toString() ? `?${q}` : ""}`);
160
+ },
161
+ delete: (args) => {
162
+ const q = new URLSearchParams({ key: args.key });
163
+ if (args.visibility) q.set("visibility", args.visibility);
164
+ return this.request(
165
+ "DELETE",
166
+ `/v1/storage/object?${q}`
167
+ );
168
+ },
169
+ url: (args) => {
170
+ const q = new URLSearchParams({ key: args.key });
171
+ if (args.visibility) q.set("visibility", args.visibility);
172
+ if (args.expiresIn != null) q.set("expires_in", String(args.expiresIn));
173
+ return this.request(
174
+ "GET",
175
+ `/v1/storage/url?${q}`
176
+ );
177
+ },
178
+ quota: () => this.request("GET", "/v1/storage/quota"),
179
+ /**
180
+ * Credit a $MNEME burn tx → extend storage capacity.
181
+ * 100 $MNEME → 1 GB / 30d
182
+ * 1000 $MNEME → 10 GB / 30d
183
+ * 10000 $MNEME → 100 GB / 30d
184
+ */
185
+ burn: (args) => this.request("POST", "/v1/storage/burn", { tx_hash: args.tx_hash })
186
+ };
125
187
  async request(method, path, body) {
126
188
  const bodyText = body === void 0 ? "" : JSON.stringify(body);
127
189
  const headers = { "Content-Type": "application/json" };
package/dist/index.d.cts CHANGED
@@ -112,6 +112,75 @@ declare class Mneme {
112
112
  }>;
113
113
  stats(): Promise<StatsResponse>;
114
114
  from<T = unknown>(table: string): Collection<T>;
115
+ readonly storage: {
116
+ upload: (args: {
117
+ key: string;
118
+ file: Blob | Uint8Array | ArrayBuffer | string;
119
+ visibility?: "public" | "private";
120
+ contentType?: string;
121
+ }) => Promise<{
122
+ ok: true;
123
+ key: string;
124
+ visibility: "public" | "private";
125
+ size: number;
126
+ content_type: string;
127
+ public_url?: string;
128
+ }>;
129
+ list: (args?: {
130
+ visibility?: "public" | "private";
131
+ prefix?: string;
132
+ }) => Promise<{
133
+ visibility: "public" | "private";
134
+ count: number;
135
+ objects: Array<{
136
+ key: string;
137
+ size: number;
138
+ last_modified: string;
139
+ public_url?: string;
140
+ }>;
141
+ }>;
142
+ delete: (args: {
143
+ key: string;
144
+ visibility?: "public" | "private";
145
+ }) => Promise<{
146
+ ok: true;
147
+ key: string;
148
+ freed_bytes: number;
149
+ }>;
150
+ url: (args: {
151
+ key: string;
152
+ visibility?: "public" | "private";
153
+ expiresIn?: number;
154
+ }) => Promise<{
155
+ url: string;
156
+ expires_in: number;
157
+ }>;
158
+ quota: () => Promise<{
159
+ wallet: string;
160
+ bytes_used: number;
161
+ bytes_limit: number;
162
+ bytes_available: number;
163
+ free_tier_bytes: number;
164
+ bonus_expires_at: string | null;
165
+ }>;
166
+ /**
167
+ * Credit a $MNEME burn tx → extend storage capacity.
168
+ * 100 $MNEME → 1 GB / 30d
169
+ * 1000 $MNEME → 10 GB / 30d
170
+ * 10000 $MNEME → 100 GB / 30d
171
+ */
172
+ burn: (args: {
173
+ tx_hash: string;
174
+ }) => Promise<{
175
+ ok: true;
176
+ tx_hash: string;
177
+ burned_tokens: number;
178
+ tier: string;
179
+ bytes_added: number;
180
+ days_added: number;
181
+ new_expires_at: string;
182
+ }>;
183
+ };
115
184
  request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
116
185
  }
117
186
  declare class Collection<T = unknown> {
package/dist/index.d.ts CHANGED
@@ -112,6 +112,75 @@ declare class Mneme {
112
112
  }>;
113
113
  stats(): Promise<StatsResponse>;
114
114
  from<T = unknown>(table: string): Collection<T>;
115
+ readonly storage: {
116
+ upload: (args: {
117
+ key: string;
118
+ file: Blob | Uint8Array | ArrayBuffer | string;
119
+ visibility?: "public" | "private";
120
+ contentType?: string;
121
+ }) => Promise<{
122
+ ok: true;
123
+ key: string;
124
+ visibility: "public" | "private";
125
+ size: number;
126
+ content_type: string;
127
+ public_url?: string;
128
+ }>;
129
+ list: (args?: {
130
+ visibility?: "public" | "private";
131
+ prefix?: string;
132
+ }) => Promise<{
133
+ visibility: "public" | "private";
134
+ count: number;
135
+ objects: Array<{
136
+ key: string;
137
+ size: number;
138
+ last_modified: string;
139
+ public_url?: string;
140
+ }>;
141
+ }>;
142
+ delete: (args: {
143
+ key: string;
144
+ visibility?: "public" | "private";
145
+ }) => Promise<{
146
+ ok: true;
147
+ key: string;
148
+ freed_bytes: number;
149
+ }>;
150
+ url: (args: {
151
+ key: string;
152
+ visibility?: "public" | "private";
153
+ expiresIn?: number;
154
+ }) => Promise<{
155
+ url: string;
156
+ expires_in: number;
157
+ }>;
158
+ quota: () => Promise<{
159
+ wallet: string;
160
+ bytes_used: number;
161
+ bytes_limit: number;
162
+ bytes_available: number;
163
+ free_tier_bytes: number;
164
+ bonus_expires_at: string | null;
165
+ }>;
166
+ /**
167
+ * Credit a $MNEME burn tx → extend storage capacity.
168
+ * 100 $MNEME → 1 GB / 30d
169
+ * 1000 $MNEME → 10 GB / 30d
170
+ * 10000 $MNEME → 100 GB / 30d
171
+ */
172
+ burn: (args: {
173
+ tx_hash: string;
174
+ }) => Promise<{
175
+ ok: true;
176
+ tx_hash: string;
177
+ burned_tokens: number;
178
+ tier: string;
179
+ bytes_added: number;
180
+ days_added: number;
181
+ new_expires_at: string;
182
+ }>;
183
+ };
115
184
  request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
116
185
  }
117
186
  declare class Collection<T = unknown> {
package/dist/index.js CHANGED
@@ -42,6 +42,24 @@ function randomNonce() {
42
42
  }
43
43
 
44
44
  // src/client.ts
45
+ async function toUint8Array(input) {
46
+ if (input instanceof Uint8Array) return input;
47
+ if (input instanceof ArrayBuffer) return new Uint8Array(input);
48
+ if (typeof Blob !== "undefined" && input instanceof Blob) {
49
+ return new Uint8Array(await input.arrayBuffer());
50
+ }
51
+ if (typeof input === "string") return new TextEncoder().encode(input);
52
+ throw new Error("unsupported file type for storage.upload");
53
+ }
54
+ function uint8ToBase64(bytes) {
55
+ const CHUNK = 32768;
56
+ const parts = [];
57
+ for (let i = 0; i < bytes.byteLength; i += CHUNK) {
58
+ parts.push(String.fromCharCode(...bytes.subarray(i, i + CHUNK)));
59
+ }
60
+ if (typeof btoa !== "undefined") return btoa(parts.join(""));
61
+ return Buffer.from(parts.join(""), "binary").toString("base64");
62
+ }
45
63
  var MnemeError = class extends Error {
46
64
  constructor(status, message) {
47
65
  super(message);
@@ -90,6 +108,50 @@ var Mneme = class {
90
108
  from(table) {
91
109
  return new Collection(this, table);
92
110
  }
111
+ // ─── Storage (Cloudflare R2 backend, $MNEME burn quota) ──────────────────
112
+ storage = {
113
+ upload: async (args) => {
114
+ const bytes = await toUint8Array(args.file);
115
+ const content_base64 = uint8ToBase64(bytes);
116
+ return this.request("POST", "/v1/storage/upload", {
117
+ key: args.key,
118
+ visibility: args.visibility ?? "private",
119
+ content_type: args.contentType ?? "application/octet-stream",
120
+ content_base64
121
+ });
122
+ },
123
+ list: (args) => {
124
+ const q = new URLSearchParams();
125
+ if (args?.visibility) q.set("visibility", args.visibility);
126
+ if (args?.prefix) q.set("prefix", args.prefix);
127
+ return this.request("GET", `/v1/storage/list${q.toString() ? `?${q}` : ""}`);
128
+ },
129
+ delete: (args) => {
130
+ const q = new URLSearchParams({ key: args.key });
131
+ if (args.visibility) q.set("visibility", args.visibility);
132
+ return this.request(
133
+ "DELETE",
134
+ `/v1/storage/object?${q}`
135
+ );
136
+ },
137
+ url: (args) => {
138
+ const q = new URLSearchParams({ key: args.key });
139
+ if (args.visibility) q.set("visibility", args.visibility);
140
+ if (args.expiresIn != null) q.set("expires_in", String(args.expiresIn));
141
+ return this.request(
142
+ "GET",
143
+ `/v1/storage/url?${q}`
144
+ );
145
+ },
146
+ quota: () => this.request("GET", "/v1/storage/quota"),
147
+ /**
148
+ * Credit a $MNEME burn tx → extend storage capacity.
149
+ * 100 $MNEME → 1 GB / 30d
150
+ * 1000 $MNEME → 10 GB / 30d
151
+ * 10000 $MNEME → 100 GB / 30d
152
+ */
153
+ burn: (args) => this.request("POST", "/v1/storage/burn", { tx_hash: args.tx_hash })
154
+ };
93
155
  async request(method, path, body) {
94
156
  const bodyText = body === void 0 ? "" : JSON.stringify(body);
95
157
  const headers = { "Content-Type": "application/json" };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mneme-sdk",
3
- "version": "0.0.1",
4
- "description": "TypeScript SDK for Mneme — agent-native Postgres database platform on Base. Wallet-auth, runtime DDL, pgvector built-in.",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for Mneme — agent-native Postgres + R2 storage on Base. Wallet-auth, runtime DDL, pgvector, wallet-bound files with $MNEME burn quota.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",