@oesp/sync-http 5.0.0 → 6.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
@@ -33,8 +33,9 @@ var import_meta = {};
33
33
  function getSyncConfig(overrides = {}) {
34
34
  const defaultBaseUrl = "http://oesp-sync-server:8000";
35
35
  let envBaseUrl;
36
- if (typeof process !== "undefined" && process.env?.OESP_SYNC_BASE_URL) {
37
- envBaseUrl = process.env.OESP_SYNC_BASE_URL;
36
+ const nodeEnv = globalThis?.process?.env;
37
+ if (nodeEnv?.OESP_SYNC_BASE_URL) {
38
+ envBaseUrl = nodeEnv.OESP_SYNC_BASE_URL;
38
39
  }
39
40
  if (typeof import_meta !== "undefined" && import_meta.env?.VITE_OESP_SYNC_BASE_URL) {
40
41
  envBaseUrl = import_meta.env.VITE_OESP_SYNC_BASE_URL;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,35 @@
1
- export * from "./SyncClient";
2
- export * from "./env";
1
+ interface SyncConfig {
2
+ baseUrl: string;
3
+ apiKey?: string;
4
+ timeoutMs: number;
5
+ maxChunkBytes: number;
6
+ }
7
+ declare function getSyncConfig(overrides?: Partial<SyncConfig>): SyncConfig;
8
+
9
+ interface SyncSummary {
10
+ success: boolean;
11
+ uploadedCount: number;
12
+ totalBytes: number;
13
+ sessionId?: string;
14
+ error?: string;
15
+ }
16
+ interface SyncOpts extends Partial<SyncConfig> {
17
+ sha256: (data: Uint8Array) => Uint8Array | Promise<Uint8Array>;
18
+ }
19
+ declare class OESPSyncClient {
20
+ private config;
21
+ private sha256;
22
+ constructor(opts: SyncOpts);
23
+ setBaseUrl(url: string): void;
24
+ /**
25
+ * Synchronise une liste de tokens vers le serveur
26
+ */
27
+ syncTokens(tokens: string[], deviceDid: string, opts?: {
28
+ devicePubB64?: string;
29
+ clientMeta?: any;
30
+ allowExpired?: boolean;
31
+ }): Promise<SyncSummary>;
32
+ private chunkBytes;
33
+ }
34
+
35
+ export { OESPSyncClient, type SyncConfig, type SyncOpts, type SyncSummary, getSyncConfig };
package/dist/index.js CHANGED
@@ -1,2 +1,105 @@
1
- export * from "./SyncClient";
2
- export * from "./env";
1
+ // src/SyncClient.ts
2
+ import { base64Encode } from "@oesp/core";
3
+
4
+ // src/env.ts
5
+ function getSyncConfig(overrides = {}) {
6
+ const defaultBaseUrl = "http://oesp-sync-server:8000";
7
+ let envBaseUrl;
8
+ const nodeEnv = globalThis?.process?.env;
9
+ if (nodeEnv?.OESP_SYNC_BASE_URL) {
10
+ envBaseUrl = nodeEnv.OESP_SYNC_BASE_URL;
11
+ }
12
+ if (typeof import.meta !== "undefined" && import.meta.env?.VITE_OESP_SYNC_BASE_URL) {
13
+ envBaseUrl = import.meta.env.VITE_OESP_SYNC_BASE_URL;
14
+ }
15
+ return {
16
+ baseUrl: overrides.baseUrl || envBaseUrl || defaultBaseUrl,
17
+ apiKey: overrides.apiKey,
18
+ timeoutMs: overrides.timeoutMs || 3e4,
19
+ maxChunkBytes: overrides.maxChunkBytes || 5e5
20
+ // 500KB
21
+ };
22
+ }
23
+
24
+ // src/SyncClient.ts
25
+ var OESPSyncClient = class {
26
+ constructor(opts) {
27
+ this.config = getSyncConfig(opts);
28
+ this.sha256 = opts.sha256;
29
+ }
30
+ setBaseUrl(url) {
31
+ this.config.baseUrl = url;
32
+ }
33
+ /**
34
+ * Synchronise une liste de tokens vers le serveur
35
+ */
36
+ async syncTokens(tokens, deviceDid, opts = {}) {
37
+ try {
38
+ const startRes = await fetch(`${this.config.baseUrl}/sync/start`, {
39
+ method: "POST",
40
+ headers: { "Content-Type": "application/json" },
41
+ body: JSON.stringify({
42
+ did: deviceDid,
43
+ pub: opts.devicePubB64,
44
+ meta: opts.clientMeta
45
+ })
46
+ });
47
+ if (!startRes.ok) throw new Error(`Failed to start sync: ${startRes.statusText}`);
48
+ const { session_id } = await startRes.json();
49
+ let uploadedCount = 0;
50
+ let totalBytes = 0;
51
+ const jsonlData = tokens.map((t) => JSON.stringify({ token: t })).join("\n");
52
+ const dataBytes = new TextEncoder().encode(jsonlData);
53
+ const chunks = this.chunkBytes(dataBytes, this.config.maxChunkBytes);
54
+ for (let i = 0; i < chunks.length; i++) {
55
+ const chunkRes = await fetch(`${this.config.baseUrl}/sync/upload`, {
56
+ method: "POST",
57
+ headers: {
58
+ "X-Session-ID": session_id,
59
+ "X-Chunk-Index": i.toString(),
60
+ "Content-Type": "application/octet-stream"
61
+ },
62
+ body: chunks[i]
63
+ });
64
+ if (!chunkRes.ok) throw new Error(`Failed to upload chunk ${i}: ${chunkRes.statusText}`);
65
+ totalBytes += chunks[i].length;
66
+ }
67
+ const finalHashBytes = await this.sha256(dataBytes);
68
+ const finalHash = base64Encode(finalHashBytes);
69
+ const commitRes = await fetch(`${this.config.baseUrl}/sync/commit`, {
70
+ method: "POST",
71
+ headers: { "Content-Type": "application/json" },
72
+ body: JSON.stringify({
73
+ session_id,
74
+ final_hash: finalHash,
75
+ allow_expired: opts.allowExpired ?? true
76
+ })
77
+ });
78
+ if (!commitRes.ok) throw new Error(`Failed to commit: ${commitRes.statusText}`);
79
+ return {
80
+ success: true,
81
+ uploadedCount: tokens.length,
82
+ totalBytes,
83
+ sessionId: session_id
84
+ };
85
+ } catch (e) {
86
+ return {
87
+ success: false,
88
+ uploadedCount: 0,
89
+ totalBytes: 0,
90
+ error: e.message
91
+ };
92
+ }
93
+ }
94
+ chunkBytes(data, maxSize) {
95
+ const chunks = [];
96
+ for (let i = 0; i < data.length; i += maxSize) {
97
+ chunks.push(data.slice(i, i + maxSize));
98
+ }
99
+ return chunks;
100
+ }
101
+ };
102
+ export {
103
+ OESPSyncClient,
104
+ getSyncConfig
105
+ };
package/package.json CHANGED
@@ -1,20 +1,12 @@
1
1
  {
2
2
  "name": "@oesp/sync-http",
3
- "version": "5.0.0",
3
+ "version": "6.1.0",
4
4
  "private": false,
5
5
  "description": "OESP HTTP Sync Client",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js",
14
- "require": "./dist/index.cjs"
15
- }
16
- },
17
- "sideEffects": false,
18
10
  "files": [
19
11
  "dist"
20
12
  ],
@@ -22,7 +14,7 @@
22
14
  "access": "public"
23
15
  },
24
16
  "dependencies": {
25
- "@oesp/core": "5.0.0"
17
+ "@oesp/core": "6.1.0"
26
18
  },
27
19
  "devDependencies": {
28
20
  "tsup": "^8.0.1",
@@ -30,7 +22,7 @@
30
22
  "vitest": "^1.6.0"
31
23
  },
32
24
  "scripts": {
33
- "build": "tsc -p tsconfig.build.json",
25
+ "build": "tsup src/index.ts --dts --format esm,cjs",
34
26
  "test": "vitest run",
35
27
  "lint": "tsc -p tsconfig.json --noEmit"
36
28
  }
@@ -1,26 +0,0 @@
1
- import { SyncConfig } from "./env";
2
- export interface SyncSummary {
3
- success: boolean;
4
- uploadedCount: number;
5
- totalBytes: number;
6
- sessionId?: string;
7
- error?: string;
8
- }
9
- export interface SyncOpts extends Partial<SyncConfig> {
10
- sha256: (data: Uint8Array) => Uint8Array | Promise<Uint8Array>;
11
- }
12
- export declare class OESPSyncClient {
13
- private config;
14
- private sha256;
15
- constructor(opts: SyncOpts);
16
- setBaseUrl(url: string): void;
17
- /**
18
- * Synchronise une liste de tokens vers le serveur
19
- */
20
- syncTokens(tokens: string[], deviceDid: string, opts?: {
21
- devicePubB64?: string;
22
- clientMeta?: any;
23
- allowExpired?: boolean;
24
- }): Promise<SyncSummary>;
25
- private chunkBytes;
26
- }
@@ -1,86 +0,0 @@
1
- import { base64Encode } from "@oesp/core";
2
- import { getSyncConfig } from "./env";
3
- export class OESPSyncClient {
4
- constructor(opts) {
5
- this.config = getSyncConfig(opts);
6
- this.sha256 = opts.sha256;
7
- }
8
- setBaseUrl(url) {
9
- this.config.baseUrl = url;
10
- }
11
- /**
12
- * Synchronise une liste de tokens vers le serveur
13
- */
14
- async syncTokens(tokens, deviceDid, opts = {}) {
15
- try {
16
- // 1. Démarrer la session
17
- const startRes = await fetch(`${this.config.baseUrl}/sync/start`, {
18
- method: "POST",
19
- headers: { "Content-Type": "application/json" },
20
- body: JSON.stringify({
21
- did: deviceDid,
22
- pub: opts.devicePubB64,
23
- meta: opts.clientMeta
24
- })
25
- });
26
- if (!startRes.ok)
27
- throw new Error(`Failed to start sync: ${startRes.statusText}`);
28
- const { session_id } = await startRes.json();
29
- // 2. Chunker et Upload
30
- let uploadedCount = 0;
31
- let totalBytes = 0;
32
- const jsonlData = tokens.map(t => JSON.stringify({ token: t })).join("\n");
33
- const dataBytes = new TextEncoder().encode(jsonlData);
34
- const chunks = this.chunkBytes(dataBytes, this.config.maxChunkBytes);
35
- for (let i = 0; i < chunks.length; i++) {
36
- const chunkRes = await fetch(`${this.config.baseUrl}/sync/upload`, {
37
- method: "POST",
38
- headers: {
39
- "X-Session-ID": session_id,
40
- "X-Chunk-Index": i.toString(),
41
- "Content-Type": "application/octet-stream"
42
- },
43
- body: chunks[i]
44
- });
45
- if (!chunkRes.ok)
46
- throw new Error(`Failed to upload chunk ${i}: ${chunkRes.statusText}`);
47
- totalBytes += chunks[i].length;
48
- }
49
- // 3. Commit
50
- const finalHashBytes = await this.sha256(dataBytes);
51
- const finalHash = base64Encode(finalHashBytes);
52
- const commitRes = await fetch(`${this.config.baseUrl}/sync/commit`, {
53
- method: "POST",
54
- headers: { "Content-Type": "application/json" },
55
- body: JSON.stringify({
56
- session_id,
57
- final_hash: finalHash,
58
- allow_expired: opts.allowExpired ?? true
59
- })
60
- });
61
- if (!commitRes.ok)
62
- throw new Error(`Failed to commit: ${commitRes.statusText}`);
63
- return {
64
- success: true,
65
- uploadedCount: tokens.length,
66
- totalBytes,
67
- sessionId: session_id
68
- };
69
- }
70
- catch (e) {
71
- return {
72
- success: false,
73
- uploadedCount: 0,
74
- totalBytes: 0,
75
- error: e.message
76
- };
77
- }
78
- }
79
- chunkBytes(data, maxSize) {
80
- const chunks = [];
81
- for (let i = 0; i < data.length; i += maxSize) {
82
- chunks.push(data.slice(i, i + maxSize));
83
- }
84
- return chunks;
85
- }
86
- }
package/dist/env.d.ts DELETED
@@ -1,7 +0,0 @@
1
- export interface SyncConfig {
2
- baseUrl: string;
3
- apiKey?: string;
4
- timeoutMs: number;
5
- maxChunkBytes: number;
6
- }
7
- export declare function getSyncConfig(overrides?: Partial<SyncConfig>): SyncConfig;
package/dist/env.js DELETED
@@ -1,20 +0,0 @@
1
- export function getSyncConfig(overrides = {}) {
2
- const defaultBaseUrl = "http://oesp-sync-server:8000";
3
- let envBaseUrl;
4
- // Node.js
5
- if (typeof process !== "undefined" && process.env?.OESP_SYNC_BASE_URL) {
6
- envBaseUrl = process.env.OESP_SYNC_BASE_URL;
7
- }
8
- // Vite / Web
9
- // @ts-ignore
10
- if (typeof import.meta !== "undefined" && import.meta.env?.VITE_OESP_SYNC_BASE_URL) {
11
- // @ts-ignore
12
- envBaseUrl = import.meta.env.VITE_OESP_SYNC_BASE_URL;
13
- }
14
- return {
15
- baseUrl: overrides.baseUrl || envBaseUrl || defaultBaseUrl,
16
- apiKey: overrides.apiKey,
17
- timeoutMs: overrides.timeoutMs || 30000,
18
- maxChunkBytes: overrides.maxChunkBytes || 500000, // 500KB
19
- };
20
- }