kaiwen-core-js 0.1.0 → 0.1.2

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/app.d.ts CHANGED
@@ -15,6 +15,7 @@ export declare class KaiwenApp {
15
15
  login(mnemonic: string): Promise<void>;
16
16
  saveRecord(userId: string, payload: any): Promise<KWRecord>;
17
17
  getDecryptedRecord(id: string): Promise<any>;
18
+ deleteRecord(id: string): Promise<boolean>;
18
19
  pushSync(): Promise<number>;
19
20
  pullSync(): Promise<number>;
20
21
  }
package/dist/app.js CHANGED
@@ -34,8 +34,23 @@ class KaiwenApp {
34
34
  const record = await this.storage.getRecord(id);
35
35
  if (!record)
36
36
  return null;
37
+ if (record.is_deleted === 1)
38
+ return null;
39
+ if (!record.payload)
40
+ return null;
37
41
  return await engine_1.KWCryptoEngine.decryptPayload(record.payload, this.vault.getKey());
38
42
  }
43
+ async deleteRecord(id) {
44
+ const record = await this.storage.getRecord(id);
45
+ if (!record)
46
+ return false;
47
+ record.is_deleted = 1;
48
+ record.payload = ""; // Empty payload for tombstones
49
+ record.updated_at = Date.now() / 1000;
50
+ record.logical_clock += 1;
51
+ record.is_synced = 0;
52
+ return await this.storage.saveRecord(id, record);
53
+ }
39
54
  async pushSync() {
40
55
  return await this.pipeline.pushSync(this.appId);
41
56
  }
@@ -38,7 +38,8 @@ class KWCryptoEngine {
38
38
  const masterKeyRaw = await subtle.deriveBits({ name: "PBKDF2", salt: pbkdf2Salt, iterations: 200000, hash: "SHA-256" }, pbkdf2KeyMaterial, 256);
39
39
  // 2. HKDF App Key Derivation (matches Python)
40
40
  const hkdfKeyMaterial = await subtle.importKey("raw", masterKeyRaw, { name: "HKDF" }, false, ["deriveKey"]);
41
- return await subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: encoder.encode(appId) }, hkdfKeyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
41
+ return await subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: encoder.encode(appId) }, hkdfKeyMaterial, { name: "AES-GCM", length: 256 }, true, // MUST BE TRUE for React Native WebView Bridge
42
+ ["encrypt", "decrypt"]);
42
43
  }
43
44
  static async encryptPayload(payload, appKey) {
44
45
  const encoder = new TextEncoder();
@@ -5,8 +5,9 @@ export declare class KWRecord {
5
5
  payload: string;
6
6
  updated_at: number;
7
7
  is_synced: number;
8
+ is_deleted: number;
8
9
  schema_version: number;
9
10
  logical_clock: number;
10
- constructor(id: string, app_id: string, user_id: string, payload: string, updated_at: number, is_synced?: number, schema_version?: number, logical_clock?: number);
11
+ constructor(id: string, app_id: string, user_id: string, payload: string, updated_at: number, is_synced?: number, is_deleted?: number, schema_version?: number, logical_clock?: number);
11
12
  static fromObject(obj: any): KWRecord;
12
13
  }
@@ -2,18 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KWRecord = void 0;
4
4
  class KWRecord {
5
- constructor(id, app_id, user_id, payload, updated_at, is_synced = 0, schema_version = 1, logical_clock = 1) {
5
+ constructor(id, app_id, user_id, payload, updated_at, is_synced = 0, is_deleted = 0, schema_version = 1, logical_clock = 1) {
6
6
  this.id = id;
7
7
  this.app_id = app_id;
8
8
  this.user_id = user_id;
9
9
  this.payload = payload;
10
10
  this.updated_at = updated_at;
11
11
  this.is_synced = is_synced;
12
+ this.is_deleted = is_deleted;
12
13
  this.schema_version = schema_version;
13
14
  this.logical_clock = logical_clock;
14
15
  }
15
16
  static fromObject(obj) {
16
- return new KWRecord(obj.id, obj.app_id, obj.user_id, obj.payload, obj.updated_at, obj.is_synced, obj.schema_version, obj.logical_clock);
17
+ return new KWRecord(obj.id, obj.app_id, obj.user_id, obj.payload, obj.updated_at, obj.is_synced, obj.is_deleted || 0, obj.schema_version, obj.logical_clock);
17
18
  }
18
19
  }
19
20
  exports.KWRecord = KWRecord;
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaiwen-core-js",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Kaiwen Cloud Ecosystem SDK for TypeScript & JavaScript environments.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/app.ts CHANGED
@@ -47,9 +47,24 @@ export class KaiwenApp {
47
47
  async getDecryptedRecord(id: string): Promise<any> {
48
48
  const record = await this.storage.getRecord(id);
49
49
  if (!record) return null;
50
+ if (record.is_deleted === 1) return null;
51
+ if (!record.payload) return null;
50
52
  return await KWCryptoEngine.decryptPayload(record.payload, this.vault.getKey());
51
53
  }
52
54
 
55
+ async deleteRecord(id: string): Promise<boolean> {
56
+ const record = await this.storage.getRecord(id);
57
+ if (!record) return false;
58
+
59
+ record.is_deleted = 1;
60
+ record.payload = ""; // Empty payload for tombstones
61
+ record.updated_at = Date.now() / 1000;
62
+ record.logical_clock += 1;
63
+ record.is_synced = 0;
64
+
65
+ return await this.storage.saveRecord(id, record);
66
+ }
67
+
53
68
  async pushSync(): Promise<number> {
54
69
  return await this.pipeline.pushSync(this.appId);
55
70
  }
@@ -54,7 +54,7 @@ export class KWCryptoEngine {
54
54
  { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: encoder.encode(appId) },
55
55
  hkdfKeyMaterial,
56
56
  { name: "AES-GCM", length: 256 },
57
- false,
57
+ true, // MUST BE TRUE for React Native WebView Bridge
58
58
  ["encrypt", "decrypt"]
59
59
  );
60
60
  }
@@ -6,6 +6,7 @@ export class KWRecord {
6
6
  public payload: string,
7
7
  public updated_at: number,
8
8
  public is_synced: number = 0,
9
+ public is_deleted: number = 0,
9
10
  public schema_version: number = 1,
10
11
  public logical_clock: number = 1
11
12
  ) {}
@@ -13,7 +14,7 @@ export class KWRecord {
13
14
  static fromObject(obj: any): KWRecord {
14
15
  return new KWRecord(
15
16
  obj.id, obj.app_id, obj.user_id, obj.payload,
16
- obj.updated_at, obj.is_synced, obj.schema_version, obj.logical_clock
17
+ obj.updated_at, obj.is_synced, obj.is_deleted || 0, obj.schema_version, obj.logical_clock
17
18
  );
18
19
  }
19
20
  }