a2a-memory 0.11.5 → 0.11.6
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/LICENSE +7 -19
- package/README.md +1 -1
- package/dist/a2a/client.js +1 -252
- package/dist/a2a/discovery.js +1 -115
- package/dist/a2a/index.js +1 -8
- package/dist/a2a/types.js +1 -42
- package/dist/adapters/anthropic.js +1 -117
- package/dist/chunking/chunker.js +1 -163
- package/dist/claude/sync.js +1 -298
- package/dist/cli/commands/add.js +1 -80
- package/dist/cli/commands/claude-sync.js +1 -70
- package/dist/cli/commands/cleanup.js +1 -83
- package/dist/cli/commands/config.js +1 -79
- package/dist/cli/commands/edit.js +1 -69
- package/dist/cli/commands/embed.js +1 -92
- package/dist/cli/commands/extract.js +1 -103
- package/dist/cli/commands/health.js +1 -105
- package/dist/cli/commands/list.js +1 -46
- package/dist/cli/commands/migrate-chunks.js +1 -205
- package/dist/cli/commands/migrate-file-refs.js +1 -183
- package/dist/cli/commands/proficiency.js +1 -146
- package/dist/cli/commands/rm.js +1 -64
- package/dist/cli/commands/search.js +1 -90
- package/dist/cli/commands/setup-wizard.js +1 -387
- package/dist/cli/commands/setup.js +1 -170
- package/dist/cli/commands/skill.js +1 -151
- package/dist/cli/commands/status.js +1 -70
- package/dist/cli/commands/sync.js +1 -202
- package/dist/cli/commands/team.js +1 -142
- package/dist/cli/index.js +1 -87
- package/dist/config/manager.js +1 -372
- package/dist/db/database.js +1 -1400
- package/dist/embedding/e5-provider.js +1 -147
- package/dist/embedding/index.js +1 -34
- package/dist/embedding/local-provider.js +1 -157
- package/dist/embedding/openai-provider.js +1 -92
- package/dist/embedding/quantization.js +1 -89
- package/dist/extraction/dedup-manager.js +1 -161
- package/dist/extraction/emotion-filter.js +1 -33
- package/dist/extraction/extractor.js +1 -648
- package/dist/extraction/file-reference.js +1 -77
- package/dist/extraction/filter.js +1 -86
- package/dist/extraction/scorer.js +1 -142
- package/dist/extraction/similarity.js +1 -85
- package/dist/hooks/client-factory.js +1 -44
- package/dist/hooks/post-tool-use.js +1 -518
- package/dist/hooks/pre-compact.js +1 -209
- package/dist/hooks/session-end.js +1 -633
- package/dist/hooks/session-start.js +1 -549
- package/dist/hooks/shared.js +1 -110
- package/dist/hooks/user-prompt-submit.js +1 -316
- package/dist/i18n/index.js +1 -2
- package/dist/i18n/messages.js +1 -150
- package/dist/index.js +1 -43
- package/dist/lifecycle/cleanup-scheduler.js +1 -137
- package/dist/lifecycle/cleanup.js +1 -116
- package/dist/lifecycle/index.js +1 -13
- package/dist/lifecycle/quality-scorer.js +1 -46
- package/dist/lifecycle/tiering.js +1 -246
- package/dist/llm/client.js +1 -226
- package/dist/llm/index.js +1 -5
- package/dist/proficiency/actr-engine.js +1 -106
- package/dist/proficiency/detection.js +1 -77
- package/dist/proficiency/index.js +1 -9
- package/dist/proficiency/tracker.js +1 -173
- package/dist/proficiency/types.js +1 -8
- package/dist/providers/adapters.js +1 -140
- package/dist/providers/detector.js +1 -57
- package/dist/search/adaptive-router.js +1 -93
- package/dist/search/index.js +1 -9
- package/dist/search/ranker.js +1 -171
- package/dist/search/reranker.js +1 -155
- package/dist/session/parser.js +1 -130
- package/dist/skill/evaluator.js +1 -509
- package/dist/skill/index.js +1 -7
- package/dist/skill/types.js +1 -7
- package/dist/sync/client.js +1 -597
- package/dist/sync/encryption.js +1 -203
- package/dist/sync/index.js +1 -12
- package/dist/sync/queue.js +1 -214
- package/dist/sync/scheduler.js +1 -140
- package/dist/sync/synchronizer.js +1 -241
- package/dist/sync/team-synchronizer.js +1 -204
- package/dist/sync/vector-clock.js +1 -70
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -132
- package/dist/utils/keychain.js +1 -170
- package/dist/utils/logger.js +1 -128
- package/package.json +14 -10
- package/dist/a2a/client.d.ts.map +0 -1
- package/dist/a2a/client.js.map +0 -1
- package/dist/a2a/discovery.d.ts.map +0 -1
- package/dist/a2a/discovery.js.map +0 -1
- package/dist/a2a/index.d.ts.map +0 -1
- package/dist/a2a/index.js.map +0 -1
- package/dist/a2a/types.d.ts.map +0 -1
- package/dist/a2a/types.js.map +0 -1
- package/dist/adapters/anthropic.d.ts.map +0 -1
- package/dist/adapters/anthropic.js.map +0 -1
- package/dist/chunking/chunker.d.ts.map +0 -1
- package/dist/chunking/chunker.js.map +0 -1
- package/dist/claude/sync.d.ts.map +0 -1
- package/dist/claude/sync.js.map +0 -1
- package/dist/cli/commands/add.d.ts.map +0 -1
- package/dist/cli/commands/add.js.map +0 -1
- package/dist/cli/commands/claude-sync.d.ts.map +0 -1
- package/dist/cli/commands/claude-sync.js.map +0 -1
- package/dist/cli/commands/cleanup.d.ts.map +0 -1
- package/dist/cli/commands/cleanup.js.map +0 -1
- package/dist/cli/commands/config.d.ts.map +0 -1
- package/dist/cli/commands/config.js.map +0 -1
- package/dist/cli/commands/edit.d.ts.map +0 -1
- package/dist/cli/commands/edit.js.map +0 -1
- package/dist/cli/commands/embed.d.ts.map +0 -1
- package/dist/cli/commands/embed.js.map +0 -1
- package/dist/cli/commands/extract.d.ts.map +0 -1
- package/dist/cli/commands/extract.js.map +0 -1
- package/dist/cli/commands/health.d.ts.map +0 -1
- package/dist/cli/commands/health.js.map +0 -1
- package/dist/cli/commands/list.d.ts.map +0 -1
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/migrate-chunks.d.ts.map +0 -1
- package/dist/cli/commands/migrate-chunks.js.map +0 -1
- package/dist/cli/commands/migrate-file-refs.d.ts.map +0 -1
- package/dist/cli/commands/migrate-file-refs.js.map +0 -1
- package/dist/cli/commands/proficiency.d.ts.map +0 -1
- package/dist/cli/commands/proficiency.js.map +0 -1
- package/dist/cli/commands/rm.d.ts.map +0 -1
- package/dist/cli/commands/rm.js.map +0 -1
- package/dist/cli/commands/search.d.ts.map +0 -1
- package/dist/cli/commands/search.js.map +0 -1
- package/dist/cli/commands/setup-wizard.d.ts.map +0 -1
- package/dist/cli/commands/setup-wizard.js.map +0 -1
- package/dist/cli/commands/setup.d.ts.map +0 -1
- package/dist/cli/commands/setup.js.map +0 -1
- package/dist/cli/commands/skill.d.ts.map +0 -1
- package/dist/cli/commands/skill.js.map +0 -1
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/sync.d.ts.map +0 -1
- package/dist/cli/commands/sync.js.map +0 -1
- package/dist/cli/commands/team.d.ts.map +0 -1
- package/dist/cli/commands/team.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/config/manager.d.ts.map +0 -1
- package/dist/config/manager.js.map +0 -1
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/embedding/e5-provider.d.ts.map +0 -1
- package/dist/embedding/e5-provider.js.map +0 -1
- package/dist/embedding/index.d.ts.map +0 -1
- package/dist/embedding/index.js.map +0 -1
- package/dist/embedding/local-provider.d.ts.map +0 -1
- package/dist/embedding/local-provider.js.map +0 -1
- package/dist/embedding/openai-provider.d.ts.map +0 -1
- package/dist/embedding/openai-provider.js.map +0 -1
- package/dist/embedding/quantization.d.ts.map +0 -1
- package/dist/embedding/quantization.js.map +0 -1
- package/dist/extraction/dedup-manager.d.ts.map +0 -1
- package/dist/extraction/dedup-manager.js.map +0 -1
- package/dist/extraction/emotion-filter.d.ts.map +0 -1
- package/dist/extraction/emotion-filter.js.map +0 -1
- package/dist/extraction/extractor.d.ts.map +0 -1
- package/dist/extraction/extractor.js.map +0 -1
- package/dist/extraction/file-reference.d.ts.map +0 -1
- package/dist/extraction/file-reference.js.map +0 -1
- package/dist/extraction/filter.d.ts.map +0 -1
- package/dist/extraction/filter.js.map +0 -1
- package/dist/extraction/scorer.d.ts.map +0 -1
- package/dist/extraction/scorer.js.map +0 -1
- package/dist/extraction/similarity.d.ts.map +0 -1
- package/dist/extraction/similarity.js.map +0 -1
- package/dist/hooks/client-factory.d.ts.map +0 -1
- package/dist/hooks/client-factory.js.map +0 -1
- package/dist/hooks/post-tool-use.d.ts.map +0 -1
- package/dist/hooks/post-tool-use.js.map +0 -1
- package/dist/hooks/pre-compact.d.ts.map +0 -1
- package/dist/hooks/pre-compact.js.map +0 -1
- package/dist/hooks/session-end.d.ts.map +0 -1
- package/dist/hooks/session-end.js.map +0 -1
- package/dist/hooks/session-start.d.ts.map +0 -1
- package/dist/hooks/session-start.js.map +0 -1
- package/dist/hooks/shared.d.ts.map +0 -1
- package/dist/hooks/shared.js.map +0 -1
- package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
- package/dist/hooks/user-prompt-submit.js.map +0 -1
- package/dist/i18n/index.d.ts.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/i18n/messages.d.ts.map +0 -1
- package/dist/i18n/messages.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lifecycle/cleanup-scheduler.d.ts.map +0 -1
- package/dist/lifecycle/cleanup-scheduler.js.map +0 -1
- package/dist/lifecycle/cleanup.d.ts.map +0 -1
- package/dist/lifecycle/cleanup.js.map +0 -1
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/index.js.map +0 -1
- package/dist/lifecycle/quality-scorer.d.ts.map +0 -1
- package/dist/lifecycle/quality-scorer.js.map +0 -1
- package/dist/lifecycle/tiering.d.ts.map +0 -1
- package/dist/lifecycle/tiering.js.map +0 -1
- package/dist/llm/client.d.ts.map +0 -1
- package/dist/llm/client.js.map +0 -1
- package/dist/llm/index.d.ts.map +0 -1
- package/dist/llm/index.js.map +0 -1
- package/dist/proficiency/actr-engine.d.ts.map +0 -1
- package/dist/proficiency/actr-engine.js.map +0 -1
- package/dist/proficiency/detection.d.ts.map +0 -1
- package/dist/proficiency/detection.js.map +0 -1
- package/dist/proficiency/index.d.ts.map +0 -1
- package/dist/proficiency/index.js.map +0 -1
- package/dist/proficiency/tracker.d.ts.map +0 -1
- package/dist/proficiency/tracker.js.map +0 -1
- package/dist/proficiency/types.d.ts.map +0 -1
- package/dist/proficiency/types.js.map +0 -1
- package/dist/providers/adapters.d.ts.map +0 -1
- package/dist/providers/adapters.js.map +0 -1
- package/dist/providers/detector.d.ts.map +0 -1
- package/dist/providers/detector.js.map +0 -1
- package/dist/search/adaptive-router.d.ts.map +0 -1
- package/dist/search/adaptive-router.js.map +0 -1
- package/dist/search/index.d.ts.map +0 -1
- package/dist/search/index.js.map +0 -1
- package/dist/search/ranker.d.ts.map +0 -1
- package/dist/search/ranker.js.map +0 -1
- package/dist/search/reranker.d.ts.map +0 -1
- package/dist/search/reranker.js.map +0 -1
- package/dist/session/parser.d.ts.map +0 -1
- package/dist/session/parser.js.map +0 -1
- package/dist/skill/evaluator.d.ts.map +0 -1
- package/dist/skill/evaluator.js.map +0 -1
- package/dist/skill/index.d.ts.map +0 -1
- package/dist/skill/index.js.map +0 -1
- package/dist/skill/types.d.ts.map +0 -1
- package/dist/skill/types.js.map +0 -1
- package/dist/sync/client.d.ts.map +0 -1
- package/dist/sync/client.js.map +0 -1
- package/dist/sync/encryption.d.ts.map +0 -1
- package/dist/sync/encryption.js.map +0 -1
- package/dist/sync/index.d.ts.map +0 -1
- package/dist/sync/index.js.map +0 -1
- package/dist/sync/queue.d.ts.map +0 -1
- package/dist/sync/queue.js.map +0 -1
- package/dist/sync/scheduler.d.ts.map +0 -1
- package/dist/sync/scheduler.js.map +0 -1
- package/dist/sync/synchronizer.d.ts.map +0 -1
- package/dist/sync/synchronizer.js.map +0 -1
- package/dist/sync/team-synchronizer.d.ts.map +0 -1
- package/dist/sync/team-synchronizer.js.map +0 -1
- package/dist/sync/vector-clock.d.ts.map +0 -1
- package/dist/sync/vector-clock.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/keychain.d.ts.map +0 -1
- package/dist/utils/keychain.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
package/dist/sync/encryption.js
CHANGED
|
@@ -1,203 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E2E Encryption Module
|
|
3
|
-
*
|
|
4
|
-
* AES-256-GCM 대칭 암호화를 사용하여 메모리 content/embedding 보호
|
|
5
|
-
* Node.js 내장 crypto 모듈만 사용 (외부 의존성 없음)
|
|
6
|
-
*/
|
|
7
|
-
import { randomBytes, createCipheriv, createDecipheriv, pbkdf2Sync } from 'node:crypto';
|
|
8
|
-
// ============================================================
|
|
9
|
-
// Constants
|
|
10
|
-
// ============================================================
|
|
11
|
-
const ALGORITHM = 'aes-256-gcm';
|
|
12
|
-
const KEY_LENGTH = 32; // 256 bits
|
|
13
|
-
const IV_LENGTH = 12; // GCM recommended IV length
|
|
14
|
-
const TAG_LENGTH = 16; // GCM auth tag length
|
|
15
|
-
const SALT_LENGTH = 16;
|
|
16
|
-
const PBKDF2_ITERATIONS = 100000;
|
|
17
|
-
const PBKDF2_DIGEST = 'sha512';
|
|
18
|
-
// ============================================================
|
|
19
|
-
// Key Management
|
|
20
|
-
// ============================================================
|
|
21
|
-
/**
|
|
22
|
-
* 랜덤 암호화 키 생성 (32 bytes)
|
|
23
|
-
*/
|
|
24
|
-
export function generateEncryptionKey() {
|
|
25
|
-
return randomBytes(KEY_LENGTH);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* PBKDF2로 사용자 비밀번호에서 키 유도
|
|
29
|
-
* @param password - 사용자 입력 비밀번호
|
|
30
|
-
* @param salt - 선택적 salt (재현성 필요 시 제공)
|
|
31
|
-
* @returns 키와 salt
|
|
32
|
-
*/
|
|
33
|
-
export function deriveKey(password, salt) {
|
|
34
|
-
const actualSalt = salt ?? randomBytes(SALT_LENGTH);
|
|
35
|
-
const key = pbkdf2Sync(password, actualSalt, PBKDF2_ITERATIONS, KEY_LENGTH, PBKDF2_DIGEST);
|
|
36
|
-
return {
|
|
37
|
-
key,
|
|
38
|
-
salt: actualSalt,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
// ============================================================
|
|
42
|
-
// Content Encryption
|
|
43
|
-
// ============================================================
|
|
44
|
-
/**
|
|
45
|
-
* 텍스트 암호화 (AES-256-GCM)
|
|
46
|
-
* @param plaintext - 원본 텍스트
|
|
47
|
-
* @param key - 32 bytes 암호화 키
|
|
48
|
-
* @returns 암호화된 페이로드
|
|
49
|
-
*/
|
|
50
|
-
export function encryptContent(plaintext, key) {
|
|
51
|
-
if (key.length !== KEY_LENGTH) {
|
|
52
|
-
throw new Error(`암호화 키는 ${KEY_LENGTH} bytes여야 합니다 (현재: ${key.length})`);
|
|
53
|
-
}
|
|
54
|
-
const iv = randomBytes(IV_LENGTH);
|
|
55
|
-
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
56
|
-
const plaintextBuffer = Buffer.from(plaintext, 'utf-8');
|
|
57
|
-
const encrypted = Buffer.concat([
|
|
58
|
-
cipher.update(plaintextBuffer),
|
|
59
|
-
cipher.final(),
|
|
60
|
-
]);
|
|
61
|
-
const tag = cipher.getAuthTag();
|
|
62
|
-
return {
|
|
63
|
-
ciphertext: encrypted.toString('base64'),
|
|
64
|
-
iv: iv.toString('base64'),
|
|
65
|
-
tag: tag.toString('base64'),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* 텍스트 복호화 (AES-256-GCM)
|
|
70
|
-
* @param encrypted - 암호화된 페이로드
|
|
71
|
-
* @param key - 32 bytes 암호화 키
|
|
72
|
-
* @returns 원본 텍스트
|
|
73
|
-
* @throws 키가 잘못되었거나 데이터가 변조된 경우
|
|
74
|
-
*/
|
|
75
|
-
export function decryptContent(encrypted, key) {
|
|
76
|
-
if (key.length !== KEY_LENGTH) {
|
|
77
|
-
throw new Error(`암호화 키는 ${KEY_LENGTH} bytes여야 합니다 (현재: ${key.length})`);
|
|
78
|
-
}
|
|
79
|
-
const iv = Buffer.from(encrypted.iv, 'base64');
|
|
80
|
-
const ciphertext = Buffer.from(encrypted.ciphertext, 'base64');
|
|
81
|
-
const tag = Buffer.from(encrypted.tag, 'base64');
|
|
82
|
-
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
83
|
-
decipher.setAuthTag(tag);
|
|
84
|
-
try {
|
|
85
|
-
const decrypted = Buffer.concat([
|
|
86
|
-
decipher.update(ciphertext),
|
|
87
|
-
decipher.final(),
|
|
88
|
-
]);
|
|
89
|
-
return decrypted.toString('utf-8');
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
if (error instanceof Error) {
|
|
93
|
-
throw new Error(`복호화 실패: ${error.message} (잘못된 키 또는 데이터 변조)`);
|
|
94
|
-
}
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// ============================================================
|
|
99
|
-
// Embedding Encryption
|
|
100
|
-
// ============================================================
|
|
101
|
-
/**
|
|
102
|
-
* 임베딩 벡터 암호화
|
|
103
|
-
* @param embedding - number[] 벡터
|
|
104
|
-
* @param key - 32 bytes 암호화 키
|
|
105
|
-
* @returns base64 암호화된 문자열
|
|
106
|
-
*/
|
|
107
|
-
export function encryptEmbedding(embedding, key) {
|
|
108
|
-
// Float64Array로 변환하여 바이너리 직렬화
|
|
109
|
-
const float64Array = new Float64Array(embedding);
|
|
110
|
-
const buffer = Buffer.from(float64Array.buffer);
|
|
111
|
-
const iv = randomBytes(IV_LENGTH);
|
|
112
|
-
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
113
|
-
const encrypted = Buffer.concat([
|
|
114
|
-
cipher.update(buffer),
|
|
115
|
-
cipher.final(),
|
|
116
|
-
]);
|
|
117
|
-
const tag = cipher.getAuthTag();
|
|
118
|
-
// iv + tag + ciphertext를 하나의 버퍼로 결합
|
|
119
|
-
const combined = Buffer.concat([iv, tag, encrypted]);
|
|
120
|
-
return combined.toString('base64');
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* 임베딩 벡터 복호화
|
|
124
|
-
* @param encrypted - base64 암호화된 문자열
|
|
125
|
-
* @param key - 32 bytes 암호화 키
|
|
126
|
-
* @returns number[] 벡터
|
|
127
|
-
*/
|
|
128
|
-
export function decryptEmbedding(encrypted, key) {
|
|
129
|
-
const combined = Buffer.from(encrypted, 'base64');
|
|
130
|
-
// iv (12) + tag (16) + ciphertext
|
|
131
|
-
if (combined.length < IV_LENGTH + TAG_LENGTH) {
|
|
132
|
-
throw new Error('암호화된 임베딩 데이터가 너무 짧습니다');
|
|
133
|
-
}
|
|
134
|
-
const iv = combined.subarray(0, IV_LENGTH);
|
|
135
|
-
const tag = combined.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH);
|
|
136
|
-
const ciphertext = combined.subarray(IV_LENGTH + TAG_LENGTH);
|
|
137
|
-
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
138
|
-
decipher.setAuthTag(tag);
|
|
139
|
-
try {
|
|
140
|
-
const decrypted = Buffer.concat([
|
|
141
|
-
decipher.update(ciphertext),
|
|
142
|
-
decipher.final(),
|
|
143
|
-
]);
|
|
144
|
-
// Buffer를 Float64Array로 변환
|
|
145
|
-
const float64Array = new Float64Array(decrypted.buffer, decrypted.byteOffset, decrypted.byteLength / Float64Array.BYTES_PER_ELEMENT);
|
|
146
|
-
return Array.from(float64Array);
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
if (error instanceof Error) {
|
|
150
|
-
throw new Error(`임베딩 복호화 실패: ${error.message}`);
|
|
151
|
-
}
|
|
152
|
-
throw error;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// ============================================================
|
|
156
|
-
// Utilities
|
|
157
|
-
// ============================================================
|
|
158
|
-
/**
|
|
159
|
-
* EncryptedPayload 검증
|
|
160
|
-
*/
|
|
161
|
-
export function isValidEncryptedPayload(obj) {
|
|
162
|
-
if (typeof obj !== 'object' || obj === null)
|
|
163
|
-
return false;
|
|
164
|
-
const payload = obj;
|
|
165
|
-
return (typeof payload.ciphertext === 'string' &&
|
|
166
|
-
typeof payload.iv === 'string' &&
|
|
167
|
-
typeof payload.tag === 'string');
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* 암호화된 컨텐츠를 JSON으로 래핑
|
|
171
|
-
*/
|
|
172
|
-
export function wrapEncryptedContent(encrypted) {
|
|
173
|
-
return JSON.stringify({
|
|
174
|
-
encrypted: true,
|
|
175
|
-
data: encrypted.ciphertext,
|
|
176
|
-
iv: encrypted.iv,
|
|
177
|
-
tag: encrypted.tag,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* JSON에서 암호화된 컨텐츠 추출
|
|
182
|
-
*/
|
|
183
|
-
export function unwrapEncryptedContent(wrapped) {
|
|
184
|
-
try {
|
|
185
|
-
const parsed = JSON.parse(wrapped);
|
|
186
|
-
if (parsed.encrypted !== true)
|
|
187
|
-
return null;
|
|
188
|
-
if (typeof parsed.data !== 'string' ||
|
|
189
|
-
typeof parsed.iv !== 'string' ||
|
|
190
|
-
typeof parsed.tag !== 'string') {
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
return {
|
|
194
|
-
ciphertext: parsed.data,
|
|
195
|
-
iv: parsed.iv,
|
|
196
|
-
tag: parsed.tag,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
//# sourceMappingURL=encryption.js.map
|
|
1
|
+
(function(_0x6e7898,_0x1c5cb0){function _0x570dbc(_0x5cb9dd,_0x1f3acc){return _0x471e(_0x5cb9dd-0x158,_0x1f3acc);}const _0x247bf4=_0x6e7898();function _0x1a81e9(_0x4dab03,_0x3f1efa){return _0x471e(_0x4dab03- -0x2c2,_0x3f1efa);}while(!![]){try{const _0x5aba7a=-parseInt(_0x1a81e9(-0x21d,-0x223))/0x1*(parseInt(_0x1a81e9(-0x20e,-0x227))/0x2)+-parseInt(_0x570dbc(0x207,0x1f5))/0x3*(-parseInt(_0x1a81e9(-0x1fd,-0x210))/0x4)+parseInt(_0x1a81e9(-0x21f,-0x20e))/0x5*(parseInt(_0x570dbc(0x1f3,0x1f4))/0x6)+parseInt(_0x1a81e9(-0x219,-0x200))/0x7+-parseInt(_0x570dbc(0x22a,0x232))/0x8*(-parseInt(_0x570dbc(0x1f9,0x201))/0x9)+parseInt(_0x1a81e9(-0x224,-0x22a))/0xa+-parseInt(_0x1a81e9(-0x228,-0x224))/0xb;if(_0x5aba7a===_0x1c5cb0)break;else _0x247bf4['push'](_0x247bf4['shift']());}catch(_0x25a5d1){_0x247bf4['push'](_0x247bf4['shift']());}}}(_0x19e4,0xe2be7));import{randomBytes,createCipheriv,createDecipheriv,pbkdf2Sync}from'node:crypto';const ALGORITHM=_0x17a407(0x422,0x441)+'m',KEY_LENGTH=0x20,IV_LENGTH=0xc,TAG_LENGTH=0x10,SALT_LENGTH=0x10,PBKDF2_ITERATIONS=0x186a0,PBKDF2_DIGEST=_0x17a407(0x433,0x44f);export function generateEncryptionKey(){return randomBytes(KEY_LENGTH);}export function deriveKey(_0x5c609f,_0x2c4320){const _0x3db4fc={'RLcGI':function(_0x4358a5,_0x34115f){return _0x4358a5(_0x34115f);},'abdoF':function(_0x4cc5ca,_0x5ebeba,_0xb1108a,_0x2445a8,_0x1231f6,_0x1eeba7){return _0x4cc5ca(_0x5ebeba,_0xb1108a,_0x2445a8,_0x1231f6,_0x1eeba7);}},_0x13021c=_0x2c4320??_0x3db4fc['RLcGI'](randomBytes,SALT_LENGTH),_0x461cad=_0x3db4fc['abdoF'](pbkdf2Sync,_0x5c609f,_0x13021c,PBKDF2_ITERATIONS,KEY_LENGTH,PBKDF2_DIGEST);return{'key':_0x461cad,'salt':_0x13021c};}export function encryptContent(_0x587f8d,_0xae7202){function _0x56cb64(_0x259734,_0x2e22a1){return _0x17a407(_0x2e22a1,_0x259734- -0x32);}const _0x313c27={'DETcL':function(_0x2052e9,_0x50b35d){return _0x2052e9!==_0x50b35d;},'xWxap':'base64'};if(_0x313c27['DETcL'](_0xae7202[_0x53c42c(0x9d,0xa2)],KEY_LENGTH))throw new Error(_0x53c42c(0xb9,0xc0)+KEY_LENGTH+(_0x53c42c(0x8e,0x9c)+_0x56cb64(0x41e,0x41d))+_0xae7202['length']+')');const _0x54d5f0=randomBytes(IV_LENGTH),_0x53ffb0=createCipheriv(ALGORITHM,_0xae7202,_0x54d5f0),_0x273f37=Buffer[_0x53c42c(0x86,0x95)](_0x587f8d,'utf-8'),_0x2dd8f3=Buffer['concat']([_0x53ffb0['update'](_0x273f37),_0x53ffb0[_0x53c42c(0xb1,0x99)]()]);function _0x53c42c(_0x594dda,_0x19192a){return _0x17a407(_0x594dda,_0x19192a- -0x39b);}const _0x58a1e8=_0x53ffb0['getAuthTag']();return{'ciphertext':_0x2dd8f3[_0x56cb64(0x40d,0x419)](_0x313c27[_0x56cb64(0x419,0x41c)]),'iv':_0x54d5f0[_0x53c42c(0xba,0xa4)](_0x313c27[_0x56cb64(0x419,0x3fd)]),'tag':_0x58a1e8[_0x53c42c(0xaa,0xa4)](_0x53c42c(0xbc,0xa7))};}export function decryptContent(_0x589048,_0x1982d2){function _0x34f4e5(_0x5ae9d9,_0x21938e){return _0x450ed7(_0x21938e-0xd8,_0x5ae9d9);}const _0x528a56={'onwTF':'CTrIe','oCyUm':'jdFFM','VVSMn':_0x3def44(0x362,0x377),'sFoPx':function(_0x418709,_0x4a9098){return _0x418709!==_0x4a9098;},'jZywp':'cnCHC'};if(_0x1982d2[_0x34f4e5(0x42,0x34)]!==KEY_LENGTH){if(_0x528a56[_0x34f4e5(0x4b,0x40)]!==_0x528a56[_0x34f4e5(0x2b,0x3c)])throw new Error(_0x34f4e5(0x48,0x52)+KEY_LENGTH+('\x20bytes여야\x20합'+_0x3def44(0x370,0x380))+_0x1982d2[_0x34f4e5(0x1a,0x34)]+')');else throw new _0x354028(_0x3def44(0x345,0x353)+':\x20'+_0x399f78[_0x3def44(0x37d,0x394)]);}const _0x58e8bf=Buffer['from'](_0x589048['iv'],_0x528a56[_0x34f4e5(0x4c,0x44)]),_0x1f9137=Buffer['from'](_0x589048[_0x34f4e5(0x4e,0x58)],_0x3def44(0x362,0x345)),_0x3fbf75=Buffer[_0x3def44(0x350,0x34b)](_0x589048[_0x34f4e5(0x3c,0x20)],_0x528a56['VVSMn']),_0x3814e2=createDecipheriv(ALGORITHM,_0x1982d2,_0x58e8bf);_0x3814e2[_0x34f4e5(0x27,0x43)](_0x3fbf75);function _0x3def44(_0x19152f,_0x34e54d){return _0x450ed7(_0x19152f-0x401,_0x34e54d);}try{if(_0x528a56[_0x34f4e5(0x5a,0x4d)](_0x528a56[_0x34f4e5(0x7c,0x5d)],_0x528a56[_0x3def44(0x386,0x385)])){if(_0x519469 instanceof _0x5e27c4)throw new _0x5ad250(_0x3def44(0x345,0x339)+':\x20'+_0x35721e[_0x34f4e5(0x52,0x54)]);throw _0x536ffa;}else{const _0x326806=Buffer[_0x34f4e5(0x35,0x4e)]([_0x3814e2[_0x34f4e5(0x6e,0x50)](_0x1f9137),_0x3814e2[_0x34f4e5(0x16,0x2b)]()]);return _0x326806['toString'](_0x3def44(0x380,0x36f));}}catch(_0x17e961){if(_0x17e961 instanceof Error)throw new Error('복호화\x20실패:\x20'+_0x17e961[_0x3def44(0x37d,0x36b)]+(_0x34f4e5(0x29,0x3d)+_0x34f4e5(0x4e,0x4c)));throw _0x17e961;}}export function encryptEmbedding(_0x11e6c3,_0x3b3d7d){const _0x35e558={'IbGkW':'base64'};function _0x55e706(_0x2acc42,_0x50eb3d){return _0x17a407(_0x2acc42,_0x50eb3d- -0x4e8);}function _0x4dcd80(_0x4b1825,_0x2be29c){return _0x17a407(_0x4b1825,_0x2be29c- -0x680);}const _0x38df46=new Float64Array(_0x11e6c3),_0x47cab6=Buffer[_0x4dcd80(-0x26e,-0x250)](_0x38df46['buffer']),_0x10dfdf=randomBytes(IV_LENGTH),_0x454e23=createCipheriv(ALGORITHM,_0x3b3d7d,_0x10dfdf),_0x13b6c8=Buffer[_0x4dcd80(-0x241,-0x229)]([_0x454e23[_0x55e706(-0x9f,-0x8f)](_0x47cab6),_0x454e23[_0x55e706(-0xa0,-0xb4)]()]),_0x2a6045=_0x454e23[_0x4dcd80(-0x271,-0x255)](),_0x43ca23=Buffer[_0x55e706(-0x9d,-0x91)]([_0x10dfdf,_0x2a6045,_0x13b6c8]);return _0x43ca23[_0x4dcd80(-0x242,-0x241)](_0x35e558[_0x55e706(-0x96,-0x95)]);}function _0x17a407(_0x23c2ea,_0x43ffc1){return _0x471e(_0x43ffc1-0x38c,_0x23c2ea);}export function decryptEmbedding(_0x26006a,_0x4dd150){function _0x2ebdd4(_0x187080,_0xaaae54){return _0x450ed7(_0x187080-0x4d,_0xaaae54);}const _0xabf2fb={'xMfkQ':function(_0x3ff8f7,_0x5f0307){return _0x3ff8f7+_0x5f0307;},'xdQYp':function(_0x25f899,_0x41094a){return _0x25f899+_0x41094a;},'YYXvc':function(_0x550373,_0x1a05b9,_0xe46b8d,_0x4fca27){return _0x550373(_0x1a05b9,_0xe46b8d,_0x4fca27);},'TAMad':function(_0x31c6e9,_0x2c517f){return _0x31c6e9 instanceof _0x2c517f;}},_0x1afecd=Buffer[_0x2ebdd4(-0x64,-0x61)](_0x26006a,_0x2ebdd4(-0x52,-0x73));if(_0x1afecd[_0x2ebdd4(-0x57,-0x68)]<_0xabf2fb[_0x2ebdd4(-0x32,-0x4a)](IV_LENGTH,TAG_LENGTH))throw new Error(_0x4bb368(-0x2dc,-0x2eb)+_0x4bb368(-0x2c6,-0x2dc)+'다');const _0x3bfc29=_0x1afecd[_0x4bb368(-0x2e6,-0x2e2)](0x0,IV_LENGTH);function _0x4bb368(_0x51d9f8,_0x230ce5){return _0x450ed7(_0x51d9f8- -0x249,_0x230ce5);}const _0x20ae4c=_0x1afecd[_0x4bb368(-0x2e6,-0x2c7)](IV_LENGTH,IV_LENGTH+TAG_LENGTH),_0x6be574=_0x1afecd[_0x2ebdd4(-0x50,-0x5b)](_0xabf2fb[_0x4bb368(-0x2d0,-0x2cd)](IV_LENGTH,TAG_LENGTH)),_0x1f9d45=_0xabf2fb[_0x4bb368(-0x2fc,-0x311)](createDecipheriv,ALGORITHM,_0x4dd150,_0x3bfc29);_0x1f9d45[_0x2ebdd4(-0x48,-0x3f)](_0x20ae4c);try{const _0x5e9abf=Buffer[_0x4bb368(-0x2d3,-0x2ef)]([_0x1f9d45['update'](_0x6be574),_0x1f9d45['final']()]),_0x2d998f=new Float64Array(_0x5e9abf['buffer'],_0x5e9abf['byteOffset'],_0x5e9abf[_0x4bb368(-0x2d6,-0x2d7)]/Float64Array[_0x4bb368(-0x2c5,-0x2cc)+_0x2ebdd4(-0x5a,-0x47)]);return Array[_0x2ebdd4(-0x64,-0x6f)](_0x2d998f);}catch(_0x43d2a){if(_0xabf2fb[_0x4bb368(-0x2ec,-0x306)](_0x43d2a,Error))throw new Error(_0x2ebdd4(-0x6f,-0x7d)+':\x20'+_0x43d2a[_0x4bb368(-0x2cd,-0x2cf)]);throw _0x43d2a;}}function _0x19e4(){const _0x4a19e2=['y29Uy2f0','CgfYC2u','DxbKyxrL','Egrrwxa','7jwu7zI47zMuio2cPoUkLca','uxHIC0u','BwvZC2fNzq','mteZnJG3mtjTs1LXugG','B2jQzwn0','DxrMltG','y2LWAgvYDgv4Da','Ee1MA1e','yNvMzMvY','7j207ysW6RcaioUeIoUSTcdSP6FSIRxRI4G','qLLurvnFuevsxW','ALP5D3a','7j6e67kG65sPioUZTE2yUo2zLcdSI6tTJkG','mJKWnZGZmdjYr0XTuLO','ndjlwNrou3m','C3rYAw5N','DgfN','mteZndK5mhHKrgjxsa','z2v0qxv0AfrHzW','D0HYuNG','owDbCKfdzW','wvLyDMm','mtiXmJuWnu9qtuvfBW','zNjVBq','n0PvEM1fDG','C3rYAw5NAwz5','tuL6rei','zMLUywW','ntm5mtq5mvLYDMzPvW','DMvvBwS','igj5DgvZ7jES7jw8io2vQq','yNL0zu9MzNnLDa','CwTNv0i','ruXftuvova','nZeYmMXLrgnirW','wLLnqMu','BgvUz3rO','vefnywq','Dg9tDhjPBMC','mZy3nZqYA3vUBgTY','ywvZlti1nI1NyW','yMfZzty0','q01xsKu','C3vIyxjYyxK','B0n5vw0','icJSNPJRQRVRKjWG7ykKioUyKoUkLa','uuPjzMe','BhDQEhe','B253vey','zgf0yq','EfD4yxa','C2v0qxv0AfrHzW','vLzttw4','7jwu7zI47zMu65cCioYEHoUYOoUuQsdRJBa','C2HHnteY','64Ui64UKicJTMitSNQW6ia','mtq0ngHNthL0wq','zw5JCNLWDgvK','swjhA1C','yNL0zuXLBMD0Aa','ioUnSoYDTo2eScdRS4dSOBaP','C0zVuhG'];_0x19e4=function(){return _0x4a19e2;};return _0x19e4();}export function isValidEncryptedPayload(_0x17ac89){function _0xc2c4cb(_0x39acd9,_0x3a751d){return _0x450ed7(_0x3a751d-0x520,_0x39acd9);}const _0x56f101={'qkgWB':function(_0x12f6a5,_0x3bd254){return _0x12f6a5!==_0x3bd254;},'ZYMBe':function(_0xaad1d2,_0x5982e1){return _0xaad1d2===_0x5982e1;},'veUmk':_0x17e6f8(0x401,0x40a)};if(_0x56f101[_0x17e6f8(0x412,0x432)](typeof _0x17ac89,_0xc2c4cb(0x4ad,0x49e))||_0x56f101[_0xc2c4cb(0x486,0x47b)](_0x17ac89,null))return![];function _0x17e6f8(_0x1816b5,_0x4a1181){return _0x450ed7(_0x1816b5-0x4ba,_0x4a1181);}const _0x34902c=_0x17ac89;return typeof _0x34902c[_0x17e6f8(0x43a,0x441)]===_0xc2c4cb(0x448,0x467)&&typeof _0x34902c['iv']===_0x56f101[_0xc2c4cb(0x459,0x475)]&&typeof _0x34902c['tag']===_0x56f101[_0x17e6f8(0x40f,0x3ee)];}function _0x471e(_0x268737,_0x12fee9){_0x268737=_0x268737-0x99;const _0x19e409=_0x19e4();let _0x471e3f=_0x19e409[_0x268737];if(_0x471e['KbDZWl']===undefined){var _0x2b1fc2=function(_0x5926b7){const _0xde6dc0='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x381221='',_0x315d1b='';for(let _0x51e2c1=0x0,_0x579e7d,_0xf94f4c,_0x34e48c=0x0;_0xf94f4c=_0x5926b7['charAt'](_0x34e48c++);~_0xf94f4c&&(_0x579e7d=_0x51e2c1%0x4?_0x579e7d*0x40+_0xf94f4c:_0xf94f4c,_0x51e2c1++%0x4)?_0x381221+=String['fromCharCode'](0xff&_0x579e7d>>(-0x2*_0x51e2c1&0x6)):0x0){_0xf94f4c=_0xde6dc0['indexOf'](_0xf94f4c);}for(let _0x5942a2=0x0,_0xb2e5ed=_0x381221['length'];_0x5942a2<_0xb2e5ed;_0x5942a2++){_0x315d1b+='%'+('00'+_0x381221['charCodeAt'](_0x5942a2)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x315d1b);};_0x471e['YHKKlb']=_0x2b1fc2,_0x471e['JrYMyM']={},_0x471e['KbDZWl']=!![];}const _0x1cea48=_0x19e409[0x0],_0x7159f5=_0x268737+_0x1cea48,_0x33b810=_0x471e['JrYMyM'][_0x7159f5];return!_0x33b810?(_0x471e3f=_0x471e['YHKKlb'](_0x471e3f),_0x471e['JrYMyM'][_0x7159f5]=_0x471e3f):_0x471e3f=_0x33b810,_0x471e3f;}export function wrapEncryptedContent(_0x1150eb){function _0xe030da(_0x256474,_0x44bcb7){return _0x17a407(_0x256474,_0x44bcb7- -0x29a);}function _0x4647b2(_0xb37b5b,_0x1c2e1d){return _0x17a407(_0xb37b5b,_0x1c2e1d- -0x750);}return JSON[_0xe030da(0x191,0x198)]({'encrypted':!![],'data':_0x1150eb[_0xe030da(0x1db,0x1c7)],'iv':_0x1150eb['iv'],'tag':_0x1150eb[_0xe030da(0x1a6,0x18f)]});}function _0x450ed7(_0x48d04b,_0x14abda){return _0x471e(_0x48d04b- -0x155,_0x14abda);}export function unwrapEncryptedContent(_0x431616){function _0x234859(_0x574d62,_0x12ff4f){return _0x17a407(_0x574d62,_0x12ff4f- -0x490);}const _0x3f9242={'wHrRx':function(_0x55d6de,_0xb3d132){return _0x55d6de/_0xb3d132;},'MIzDB':function(_0x5aa846,_0x227ef7){return _0x5aa846!==_0x227ef7;},'QJIfa':'string','CMWJE':'YBlVC'};function _0x24648e(_0x462423,_0x44e2c5){return _0x17a407(_0x44e2c5,_0x462423- -0x6f7);}try{if(_0x3f9242[_0x24648e(-0x2c4,-0x2b9)](_0x234859(-0x54,-0x34),_0x234859(-0x67,-0x48))){const _0x3d619d=JSON[_0x234859(-0x57,-0x38)](_0x431616);if(_0x3d619d[_0x234859(-0x26,-0x3e)]!==!![])return null;if(typeof _0x3d619d[_0x234859(-0x40,-0x46)]!==_0x3f9242[_0x24648e(-0x2b0,-0x2a3)]||typeof _0x3d619d['iv']!==_0x3f9242[_0x24648e(-0x2b0,-0x2ce)]||_0x3f9242[_0x24648e(-0x2c4,-0x2ae)](typeof _0x3d619d[_0x234859(-0x50,-0x67)],'string')){if(_0x3f9242[_0x234859(-0x5f,-0x4d)]==='YBlVC')return null;else{const _0x305997=_0x317591[_0x24648e(-0x2a0,-0x2a6)]([_0x2ee2da[_0x234859(-0x36,-0x37)](_0x929dc9),_0x4136f8[_0x234859(-0x63,-0x5c)]()]),_0x2a031f=new _0x1b6e7b(_0x305997[_0x234859(-0x1b,-0x2d)],_0x305997[_0x234859(-0x56,-0x58)],hbuILv[_0x24648e(-0x2cb,-0x2df)](_0x305997[_0x234859(-0x4e,-0x3c)],_0x437234[_0x24648e(-0x292,-0x2a7)+'ELEMENT']));return _0x2d7aff[_0x24648e(-0x2c7,-0x2e6)](_0x2a031f);}}return{'ciphertext':_0x3d619d[_0x234859(-0x4b,-0x46)],'iv':_0x3d619d['iv'],'tag':_0x3d619d[_0x24648e(-0x2ce,-0x2b4)]};}else return null;}catch{return null;}}
|
package/dist/sync/index.js
CHANGED
|
@@ -1,12 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Sync Module - A2A Server Synchronization
|
|
3
|
-
*/
|
|
4
|
-
export { A2AClient } from './client.js';
|
|
5
|
-
export { MemorySynchronizer } from './synchronizer.js';
|
|
6
|
-
export { SyncQueue, mapCategory, mapTier } from './queue.js';
|
|
7
|
-
export { LocalVectorClock } from './vector-clock.js';
|
|
8
|
-
export { TeamSynchronizer } from './team-synchronizer.js';
|
|
9
|
-
export { SyncScheduler } from './scheduler.js';
|
|
10
|
-
// Encryption
|
|
11
|
-
export { encryptContent, decryptContent, encryptEmbedding, decryptEmbedding, deriveKey, generateEncryptionKey, wrapEncryptedContent, unwrapEncryptedContent, isValidEncryptedPayload, } from './encryption.js';
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
(function(_0x45de07,_0x314e97){function _0xc2efd1(_0x198b13,_0x2791fd){return _0x5264(_0x198b13-0x168,_0x2791fd);}var _0x18b8f7=_0x45de07();function _0x2413ac(_0x20abbb,_0x1f67ef){return _0x5264(_0x1f67ef-0x127,_0x20abbb);}while(!![]){try{var _0x3611b9=-parseInt(_0xc2efd1(0x224,0x224))/0x1+-parseInt(_0xc2efd1(0x222,0x223))/0x2+-parseInt(_0xc2efd1(0x221,0x21f))/0x3*(parseInt(_0xc2efd1(0x21d,0x21f))/0x4)+-parseInt(_0xc2efd1(0x21e,0x220))/0x5*(-parseInt(_0x2413ac(0x1e7,0x1e4))/0x6)+-parseInt(_0xc2efd1(0x220,0x21c))/0x7+-parseInt(_0x2413ac(0x1e6,0x1e2))/0x8*(parseInt(_0xc2efd1(0x21f,0x224))/0x9)+parseInt(_0xc2efd1(0x226,0x224))/0xa;if(_0x3611b9===_0x314e97)break;else _0x18b8f7['push'](_0x18b8f7['shift']());}catch(_0x1914cb){_0x18b8f7['push'](_0x18b8f7['shift']());}}}(_0x2121,0x32251));export{A2AClient}from'./client.js';export{MemorySynchronizer}from'./synchronizer.js';export{SyncQueue,mapCategory,mapTier}from'./queue.js';export{LocalVectorClock}from'./vector-clock.js';export{TeamSynchronizer}from'./team-synchronizer.js';function _0x5264(_0x3967ea,_0x5c6d5a){_0x3967ea=_0x3967ea-0xb5;var _0x21219a=_0x2121();var _0x5264a3=_0x21219a[_0x3967ea];if(_0x5264['aagGQL']===undefined){var _0x2ef7f7=function(_0x25edd6){var _0x5b3da0='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0xb2d259='',_0x2e0779='';for(var _0x26045b=0x0,_0x2afb15,_0x5ddc47,_0x11b4eb=0x0;_0x5ddc47=_0x25edd6['charAt'](_0x11b4eb++);~_0x5ddc47&&(_0x2afb15=_0x26045b%0x4?_0x2afb15*0x40+_0x5ddc47:_0x5ddc47,_0x26045b++%0x4)?_0xb2d259+=String['fromCharCode'](0xff&_0x2afb15>>(-0x2*_0x26045b&0x6)):0x0){_0x5ddc47=_0x5b3da0['indexOf'](_0x5ddc47);}for(var _0x9bf20b=0x0,_0x2d459f=_0xb2d259['length'];_0x9bf20b<_0x2d459f;_0x9bf20b++){_0x2e0779+='%'+('00'+_0xb2d259['charCodeAt'](_0x9bf20b)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2e0779);};_0x5264['LgIEtF']=_0x2ef7f7,_0x5264['nSaXXB']={},_0x5264['aagGQL']=!![];}var _0x40d137=_0x21219a[0x0],_0x11ec8b=_0x3967ea+_0x40d137,_0x127601=_0x5264['nSaXXB'][_0x11ec8b];return!_0x127601?(_0x5264a3=_0x5264['LgIEtF'](_0x5264a3),_0x5264['nSaXXB'][_0x11ec8b]=_0x5264a3):_0x5264a3=_0x127601,_0x5264a3;}export{SyncScheduler}from'./scheduler.js';export{encryptContent,decryptContent,encryptEmbedding,decryptEmbedding,deriveKey,generateEncryptionKey,wrapEncryptedContent,unwrapEncryptedContent,isValidEncryptedPayload}from'./encryption.js';function _0x2121(){var _0x1ebf25=['mJC1mJHHAfbPv0m','mtqYotzOvKnywM0','mti1nJiYBhzSwMrA','odC4mtq0mgPWB0HKBG','nZC1ndq4s21gzfHK','otv2EfHnr08','odu1vuvSzLft','mtGWode5muPjCw9gra','nKnwEKvdCG','mty2nJuYqNvZA0Ti'];_0x2121=function(){return _0x1ebf25;};return _0x2121();}
|
package/dist/sync/queue.js
CHANGED
|
@@ -1,214 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Write-Behind Sync Queue
|
|
3
|
-
*
|
|
4
|
-
* 로컬 DB에 저장된 메모리를 원격 서버로 일괄 push합니다.
|
|
5
|
-
* 로컬 DB = 캐시, 원격 서버 = Single Source of Truth.
|
|
6
|
-
*/
|
|
7
|
-
import { createHash } from 'node:crypto';
|
|
8
|
-
import { scoreQuality } from '../lifecycle/quality-scorer.js';
|
|
9
|
-
// ============================================================
|
|
10
|
-
// Category/Tier 매핑 (로컬 레거시 → 서버 호환)
|
|
11
|
-
// ============================================================
|
|
12
|
-
// Minimal LifecycleConfig required by scoreQuality (only ttlDays is used for freshness calc)
|
|
13
|
-
const QUALITY_LIFECYCLE_CONFIG = {
|
|
14
|
-
ttlDays: 90,
|
|
15
|
-
maxMemories: 20000,
|
|
16
|
-
cleanupOnSessionEnd: false,
|
|
17
|
-
qualityThreshold: 0.3,
|
|
18
|
-
};
|
|
19
|
-
const CATEGORY_MAP = {
|
|
20
|
-
preference: 'convention',
|
|
21
|
-
};
|
|
22
|
-
const TIER_MAP = {
|
|
23
|
-
procedural: 'semantic',
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* 로컬 category를 서버 호환 category로 변환
|
|
27
|
-
*/
|
|
28
|
-
export function mapCategory(category) {
|
|
29
|
-
return (CATEGORY_MAP[category] ?? category);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* 로컬 tier를 서버 호환 tier로 변환
|
|
33
|
-
*/
|
|
34
|
-
export function mapTier(tier) {
|
|
35
|
-
return (TIER_MAP[tier] ?? tier);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 컨텐츠 해시 생성 (중복 제거용)
|
|
39
|
-
*/
|
|
40
|
-
function computeContentHash(content) {
|
|
41
|
-
return createHash('sha256').update(content.trim().toLowerCase()).digest('hex').substring(0, 16);
|
|
42
|
-
}
|
|
43
|
-
export class SyncQueue {
|
|
44
|
-
db;
|
|
45
|
-
client;
|
|
46
|
-
constructor(db, client) {
|
|
47
|
-
this.db = db;
|
|
48
|
-
this.client = client;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* 메모리를 sync 대기 상태로 설정 (~1ms)
|
|
52
|
-
*/
|
|
53
|
-
enqueue(memoryId) {
|
|
54
|
-
this.db.setSyncStatus(memoryId, null, 'pending');
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* pending 메모리를 배치로 일괄 push (100개씩)
|
|
58
|
-
* 중복 제거: pending 내부 중복만 제거 (서버 측에서 synced 대비 중복은 처리)
|
|
59
|
-
*
|
|
60
|
-
* Parent-Child FK 안전:
|
|
61
|
-
* 1단계 — Parent (parentId 없는 항목) push → remote_id 획득
|
|
62
|
-
* 2단계 — Children의 parentId를 remote parent_id로 변환 후 push
|
|
63
|
-
*/
|
|
64
|
-
async flush(options) {
|
|
65
|
-
const startTime = Date.now();
|
|
66
|
-
const timeoutMs = options?.timeoutMs ?? 300000; // 기본 5분
|
|
67
|
-
const result = {
|
|
68
|
-
pushed: 0,
|
|
69
|
-
failed: 0,
|
|
70
|
-
errors: [],
|
|
71
|
-
duration: 0,
|
|
72
|
-
syncedItems: [],
|
|
73
|
-
};
|
|
74
|
-
const BATCH_SIZE = 100;
|
|
75
|
-
const pending = this.db.getPendingSyncMemories();
|
|
76
|
-
if (pending.length === 0) {
|
|
77
|
-
result.duration = Date.now() - startTime;
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
// 중복 제거: pending 내부 중복만 제거 (서버 측에서 synced 대비 중복은 처리)
|
|
81
|
-
const pendingHashes = new Map(); // hash → first memoryId
|
|
82
|
-
const dedupedPending = pending.filter(m => {
|
|
83
|
-
const hash = computeContentHash(m.content);
|
|
84
|
-
if (pendingHashes.has(hash)) {
|
|
85
|
-
// 중복이므로 synced로 마킹하고 건너뛰기
|
|
86
|
-
this.db.setSyncStatus(m.id, null, 'synced');
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
pendingHashes.set(hash, m.id);
|
|
90
|
-
return true;
|
|
91
|
-
});
|
|
92
|
-
// Parent/독립 메모리와 Children 분리
|
|
93
|
-
const parents = dedupedPending.filter(m => !m.parentId);
|
|
94
|
-
const children = dedupedPending.filter(m => !!m.parentId);
|
|
95
|
-
// local parent_id → remote parent_id 매핑
|
|
96
|
-
// 이미 synced된 parent의 remote_id를 미리 조회
|
|
97
|
-
const parentRemoteMap = new Map();
|
|
98
|
-
for (const child of children) {
|
|
99
|
-
if (child.parentId && !parentRemoteMap.has(child.parentId)) {
|
|
100
|
-
const parentSync = this.db.getSyncStatus(child.parentId);
|
|
101
|
-
if (parentSync?.remoteId) {
|
|
102
|
-
parentRemoteMap.set(child.parentId, parentSync.remoteId);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// ── Phase 1: Parents + 독립 메모리 push ──
|
|
107
|
-
await this.pushBatches(parents, BATCH_SIZE, startTime, timeoutMs, result, parentRemoteMap);
|
|
108
|
-
// ── Phase 2: Children push (parent_id → remote_id 변환) ──
|
|
109
|
-
if (children.length > 0 && (timeoutMs === 0 || Date.now() - startTime < timeoutMs)) {
|
|
110
|
-
// 매핑 불가능한 children은 pending 유지
|
|
111
|
-
const mappable = children.filter(m => parentRemoteMap.has(m.parentId));
|
|
112
|
-
const unmappable = children.filter(m => !parentRemoteMap.has(m.parentId));
|
|
113
|
-
if (unmappable.length > 0) {
|
|
114
|
-
result.errors.push(`${unmappable.length}개 child — parent remote_id 미확인 (다음 flush에서 재시도)`);
|
|
115
|
-
}
|
|
116
|
-
await this.pushBatches(mappable, BATCH_SIZE, startTime, timeoutMs, result, parentRemoteMap);
|
|
117
|
-
}
|
|
118
|
-
result.duration = Date.now() - startTime;
|
|
119
|
-
return result;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* 배치 단위 push 공통 로직
|
|
123
|
-
* parentRemoteMap: push 성공 시 local_id→remote_id 매핑 업데이트 (Phase 1→Phase 2 전달용)
|
|
124
|
-
*/
|
|
125
|
-
async pushBatches(items, batchSize, startTime, timeoutMs, result, parentRemoteMap) {
|
|
126
|
-
for (let i = 0; i < items.length; i += batchSize) {
|
|
127
|
-
if (timeoutMs > 0 && Date.now() - startTime > timeoutMs) {
|
|
128
|
-
const remaining = items.length - i;
|
|
129
|
-
result.errors.push(`타임아웃: ${remaining}개 미처리`);
|
|
130
|
-
result.failed += remaining;
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
const batch = items.slice(i, i + batchSize);
|
|
134
|
-
try {
|
|
135
|
-
const batchResult = await this.client.createMemoriesBatch(batch.map((m) => {
|
|
136
|
-
// quality_score: 이미 계산된 값이 있으면 사용, 없으면 실시간 계산
|
|
137
|
-
const quality = m.qualityScore !== undefined
|
|
138
|
-
? m.qualityScore
|
|
139
|
-
: scoreQuality(m, QUALITY_LIFECYCLE_CONFIG).overall;
|
|
140
|
-
return {
|
|
141
|
-
content: m.content,
|
|
142
|
-
category: mapCategory(m.category),
|
|
143
|
-
tier: mapTier(m.tier),
|
|
144
|
-
tags: m.tags,
|
|
145
|
-
created_at: m.createdAt,
|
|
146
|
-
// Children: local parent_id → remote parent_id 변환
|
|
147
|
-
parent_id: m.parentId ? parentRemoteMap.get(m.parentId) : undefined,
|
|
148
|
-
chunk_index: m.chunkIndex ?? undefined,
|
|
149
|
-
chunk_total: m.chunkTotal ?? undefined,
|
|
150
|
-
quality_score: quality,
|
|
151
|
-
};
|
|
152
|
-
}));
|
|
153
|
-
// 성공한 항목들 synced로 업데이트 + parentRemoteMap 갱신
|
|
154
|
-
for (let j = 0; j < batchResult.ids.length; j++) {
|
|
155
|
-
if (j < batch.length && batchResult.ids[j]) {
|
|
156
|
-
this.db.setSyncStatus(batch[j].id, batchResult.ids[j], 'synced');
|
|
157
|
-
// 이 항목이 다른 child의 parent일 수 있으므로 매핑 등록
|
|
158
|
-
parentRemoteMap.set(batch[j].id, batchResult.ids[j]);
|
|
159
|
-
result.syncedItems.push({ localId: batch[j].id, remoteId: batchResult.ids[j] });
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
result.pushed += batchResult.created;
|
|
163
|
-
result.failed += batchResult.failed;
|
|
164
|
-
if (batchResult.errors.length > 0) {
|
|
165
|
-
result.errors.push(...batchResult.errors);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
catch (error) {
|
|
169
|
-
result.errors.push(`배치 실패: ${error instanceof Error ? error.message : String(error)}`);
|
|
170
|
-
result.failed += batch.length;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* 미동기화 tombstone을 원격 서버에서 삭제
|
|
176
|
-
*/
|
|
177
|
-
async flushTombstones() {
|
|
178
|
-
const tombstones = this.db.getUnsyncedTombstones();
|
|
179
|
-
let deleted = 0;
|
|
180
|
-
const errors = [];
|
|
181
|
-
for (const tombstone of tombstones) {
|
|
182
|
-
const syncStatus = this.db.getSyncStatus(tombstone.memoryId);
|
|
183
|
-
if (!syncStatus?.remoteId) {
|
|
184
|
-
// 원격에 push된 적 없는 메모리 — tombstone만 synced 처리
|
|
185
|
-
this.db.markTombstoneSynced(tombstone.memoryId);
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
try {
|
|
189
|
-
await this.client.deleteMemory(syncStatus.remoteId);
|
|
190
|
-
this.db.markTombstoneSynced(tombstone.memoryId);
|
|
191
|
-
deleted++;
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
195
|
-
// 404는 이미 삭제된 것 — synced 처리
|
|
196
|
-
if (msg.includes('404') || msg.includes('not found') || msg.includes('Not Found')) {
|
|
197
|
-
this.db.markTombstoneSynced(tombstone.memoryId);
|
|
198
|
-
deleted++;
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
errors.push(`삭제 실패 (${tombstone.memoryId}): ${msg}`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return { deleted, errors };
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* 대기 중인 메모리 수
|
|
209
|
-
*/
|
|
210
|
-
getPendingCount() {
|
|
211
|
-
return this.db.getPendingSyncMemories().length;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
//# sourceMappingURL=queue.js.map
|
|
1
|
+
(function(_0x2b16ba,_0x2b4199){function _0x1c1836(_0x21dd70,_0x4bf983){return _0x1b5a(_0x4bf983-0x26f,_0x21dd70);}function _0x3c4008(_0x4c3382,_0x10e5a9){return _0x1b5a(_0x4c3382- -0x151,_0x10e5a9);}const _0x136cea=_0x2b16ba();while(!![]){try{const _0x260e21=parseInt(_0x3c4008(0xf1,0x11a))/0x1*(parseInt(_0x1c1836(0x473,0x466))/0x2)+-parseInt(_0x1c1836(0x4a3,0x4ab))/0x3*(-parseInt(_0x1c1836(0x455,0x46c))/0x4)+-parseInt(_0x1c1836(0x4b3,0x497))/0x5*(-parseInt(_0x1c1836(0x4b5,0x496))/0x6)+parseInt(_0x1c1836(0x431,0x45f))/0x7+-parseInt(_0x1c1836(0x4ab,0x47c))/0x8*(-parseInt(_0x3c4008(0xb9,0xc5))/0x9)+-parseInt(_0x3c4008(0xd9,0xd4))/0xa*(parseInt(_0x3c4008(0xc1,0xa5))/0xb)+-parseInt(_0x3c4008(0xa0,0x8d))/0xc;if(_0x260e21===_0x2b4199)break;else _0x136cea['push'](_0x136cea['shift']());}catch(_0x1ad5e8){_0x136cea['push'](_0x136cea['shift']());}}}(_0x7c10,0x8f75a));function _0x2f55fe(_0x2f19eb,_0xfecedc){return _0x1b5a(_0x2f19eb-0x1fa,_0xfecedc);}import{createHash}from'node:crypto';import{scoreQuality}from'../lifecycle/quality-scorer.js';const QUALITY_LIFECYCLE_CONFIG={'ttlDays':0x5a,'maxMemories':0x4e20,'cleanupOnSessionEnd':![],'qualityThreshold':0.3};function _0x1df448(_0x236a8e,_0x18a1ef){return _0x1b5a(_0x18a1ef-0x279,_0x236a8e);}const CATEGORY_MAP={'preference':_0x1df448(0x4a2,0x47d)},TIER_MAP={'procedural':_0x2f55fe(0x41b,0x404)};function _0x1b5a(_0x5adad2,_0x37e2a4){_0x5adad2=_0x5adad2-0x1ec;const _0x7c10ab=_0x7c10();let _0x1b5af4=_0x7c10ab[_0x5adad2];if(_0x1b5a['ZfySBC']===undefined){var _0x258344=function(_0x35c095){const _0x122a0a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x343120='',_0x36965c='';for(let _0x4a86b2=0x0,_0x3837a3,_0x2cc262,_0x15cf1e=0x0;_0x2cc262=_0x35c095['charAt'](_0x15cf1e++);~_0x2cc262&&(_0x3837a3=_0x4a86b2%0x4?_0x3837a3*0x40+_0x2cc262:_0x2cc262,_0x4a86b2++%0x4)?_0x343120+=String['fromCharCode'](0xff&_0x3837a3>>(-0x2*_0x4a86b2&0x6)):0x0){_0x2cc262=_0x122a0a['indexOf'](_0x2cc262);}for(let _0x34027a=0x0,_0x3f77e8=_0x343120['length'];_0x34027a<_0x3f77e8;_0x34027a++){_0x36965c+='%'+('00'+_0x343120['charCodeAt'](_0x34027a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x36965c);};_0x1b5a['LLQCWM']=_0x258344,_0x1b5a['rGlGZU']={},_0x1b5a['ZfySBC']=!![];}const _0x3df036=_0x7c10ab[0x0],_0xb247cd=_0x5adad2+_0x3df036,_0x12b7ef=_0x1b5a['rGlGZU'][_0xb247cd];return!_0x12b7ef?(_0x1b5af4=_0x1b5a['LLQCWM'](_0x1b5af4),_0x1b5a['rGlGZU'][_0xb247cd]=_0x1b5af4):_0x1b5af4=_0x12b7ef,_0x1b5af4;}export function mapCategory(_0x23ce60){return CATEGORY_MAP[_0x23ce60]??_0x23ce60;}function _0x7c10(){const _0x50c8c0=['BwvZC2fNzq','BM93','ChvZAejHDgnOzq','CM9qrvG','6RcCignOAwXKiokaLca','y2XPzw50','sK9rDMK','z2v0u3LUy1n0yq','wvvbCMG','C2vTyw50Awm','uNz1tvG','DgfNCW','y29UDgvUDa','t1PZvMK','67cW7lMyioYlPo2mQdOG','mJeWq3PJDvHe','mtu3mteWre1xyvbI','AwrZ','mJmXmJGWC1HKtfPQ','C2XPy2u','y3jLyxrLzef0','Ew5eseS','Agv4','Dg9Uzxm','DhfZDuy','q291BNq','AfPZDxm','z2v0ugvUzgLUzW','uxLNt0W','BhnXrMG','y2H1BMTuB3rHBa','ktOG','zMLSDgvY','C2v0','7yoa7j6e7jwe7jUdoIa','y2f0zwDVCNK','mtCZmJjdC0vzC1m','y3jLyxrLza','vhviwxK','B21KDfq','wxnStu0','C2v0u3LUy1n0yq','nNLKywD0zG','zfrVBwjZDg9Uzq','EeTbrNK','CMvTB3rLswq','CxvHBgL0EvnJBW','AgfZ','BwvTB3j5swq','ChvZAa','B3zLCMfSBa','DhvZ','icJRI6tSNyWGzMX1C2G','nJq4mZeZngTntwrbsq','mJa2mZi5mJb0zhHZCKi','vgjMBNq','y2H1BMTjBMrLEa','C3vIC3rYAw5N','7ikT7kcCioYlPo2mQcaO','DgLTzw91De1Z','otKWmJHnzNfJCM8','EhPQr2W','Dg9mB3DLCKnHCW','BwfW','zgLNzxn0','y3jLyxrLtwvTBW','ntzQBLLXvNm','7jEq7isCioYERoYlNoUpHcK','zw5XDwv1zq','zhvYyxrPB24','BgvUz3rO','y1vsyKS','swryAMS','y29UDMvUDgLVBG','6RcCioUVUoYYMoUMRa','Cu5yCLu','zMX1C2HuB21ICW','BwfYA1rVBwjZDa','z2v0vw5ZEw5Jzq','mJu4mJq2ueLNAwPQ','C2HHmJu2','CgfYzw50swq','mtyWBMLeswfO','CgvUzgLUzW','De5IywC','u3LUy01LBw9YAq','zMfPBgvK','mZe5DNjZDxfn','B3rLx2LKioUVUo2zLEYDUa','zxjYB3jZ','C3LUy2vK','Aw5JBhvKzxm','B25Lu3LUy2vK'];_0x7c10=function(){return _0x50c8c0;};return _0x7c10();}export function mapTier(_0x4241c6){return TIER_MAP[_0x4241c6]??_0x4241c6;}function computeContentHash(_0xdb1b78){const _0x382b9b={'IdXjk':_0x1f7e0b(0x40c,0x41b)};function _0x1f7e0b(_0x4938b3,_0x4a3a3b){return _0x1df448(_0x4938b3,_0x4a3a3b- -0x8c);}function _0x44524c(_0x363731,_0x1f46f9){return _0x1df448(_0x363731,_0x1f46f9- -0x1b1);}return createHash(_0x44524c(0x2af,0x2d3))['update'](_0xdb1b78['trim']()[_0x1f7e0b(0x3e8,0x3e6)+'e']())[_0x44524c(0x2a2,0x2c3)](_0x382b9b[_0x1f7e0b(0x3f8,0x3f0)])[_0x1f7e0b(0x40f,0x3e1)](0x0,0x10);}export class SyncQueue{['db'];[_0x1df448(0x4b6,0x496)];constructor(_0x2e9f63,_0x2f3635){function _0x5c8d78(_0x3b8388,_0xcf9eec){return _0x2f55fe(_0x3b8388- -0x5dd,_0xcf9eec);}this['db']=_0x2e9f63,this[_0x5c8d78(-0x1c6,-0x1cb)]=_0x2f3635;}[_0x2f55fe(0x3f9,0x3e9)](_0x1e7bfa){function _0x320f54(_0x5ba63c,_0x1d4a83){return _0x2f55fe(_0x1d4a83- -0x353,_0x5ba63c);}function _0x488046(_0x1145ee,_0x324eea){return _0x2f55fe(_0x1145ee- -0x155,_0x324eea);}this['db'][_0x488046(0x2e6,0x2ef)+'tus'](_0x1e7bfa,null,_0x320f54(0xba,0xb5));}async['flush'](_0x382f6f){function _0x35e99a(_0x3b9d2d,_0x5d4b8e){return _0x1df448(_0x5d4b8e,_0x3b9d2d- -0x5a2);}function _0x53bf2f(_0x162a53,_0x23d64a){return _0x1df448(_0x23d64a,_0x162a53- -0x4d9);}const _0x4b03f8={'HMyQt':_0x35e99a(-0x114,-0x125),'omdtT':function(_0x2d4cc4,_0xbcd690){return _0x2d4cc4-_0xbcd690;},'Tbfnt':function(_0xddd6cc,_0x3164b3){return _0xddd6cc===_0x3164b3;},'WZncH':function(_0x2c8a97,_0x58314c){return _0x2c8a97<_0x58314c;}},_0x24718c=Date[_0x53bf2f(-0x47,-0x72)](),_0x120e71=_0x382f6f?.[_0x35e99a(-0x133,-0x155)]??0x493e0,_0x37dc86={'pushed':0x0,'failed':0x0,'errors':[],'duration':0x0,'syncedItems':[]},_0x32a841=0x64,_0x57276a=this['db']['getPending'+_0x53bf2f(-0x50,-0x72)+'es']();if(_0x4b03f8['Tbfnt'](_0x57276a[_0x35e99a(-0x128,-0x119)],0x0))return _0x37dc86[_0x35e99a(-0x129,-0x106)]=Date['now']()-_0x24718c,_0x37dc86;const _0x499bdd=new Map(),_0x3aa083=_0x57276a[_0x35e99a(-0xf1,-0xe9)](_0x59df91=>{const _0x2bf6e5=computeContentHash(_0x59df91[_0x5869f2(0x15d,0x14b)]);function _0x462d9c(_0x1c64f7,_0x3ab652){return _0x35e99a(_0x1c64f7-0x5a1,_0x3ab652);}if(_0x499bdd[_0x5869f2(0x189,0x16e)](_0x2bf6e5))return this['db'][_0x5869f2(0x18f,0x168)+_0x5869f2(0xed,0x115)](_0x59df91['id'],null,_0x4b03f8['HMyQt']),![];function _0x5869f2(_0x43e864,_0x4a024e){return _0x35e99a(_0x4a024e-0x250,_0x43e864);}return _0x499bdd[_0x5869f2(0x17d,0x160)](_0x2bf6e5,_0x59df91['id']),!![];}),_0x3e3267=_0x3aa083['filter'](_0x90940c=>!_0x90940c['parentId']),_0xa9294d=_0x3aa083[_0x53bf2f(-0x28,-0x47)](_0x433e95=>!!_0x433e95[_0x53bf2f(-0x54,-0x3a)]),_0x4eccb2=new Map();for(const _0x906e3e of _0xa9294d){if(_0x906e3e[_0x35e99a(-0x11d,-0x133)]&&!_0x4eccb2['has'](_0x906e3e[_0x35e99a(-0x11d,-0x128)])){const _0x5cca1e=this['db'][_0x35e99a(-0x10a,-0xfe)+_0x53bf2f(-0x72,-0x47)](_0x906e3e[_0x53bf2f(-0x54,-0x73)]);_0x5cca1e?.[_0x35e99a(-0xe4,-0xe0)]&&_0x4eccb2[_0x53bf2f(-0x27,-0x1c)](_0x906e3e['parentId'],_0x5cca1e[_0x53bf2f(-0x1b,-0x8)]);}}await this[_0x53bf2f(-0x46,-0x71)+'s'](_0x3e3267,_0x32a841,_0x24718c,_0x120e71,_0x37dc86,_0x4eccb2);if(_0xa9294d['length']>0x0&&(_0x4b03f8[_0x35e99a(-0x137,-0x156)](_0x120e71,0x0)||_0x4b03f8['WZncH'](_0x4b03f8[_0x53bf2f(-0x21,-0x3)](Date[_0x35e99a(-0x110,-0x135)](),_0x24718c),_0x120e71))){if(_0x4b03f8['Tbfnt'](_0x53bf2f(-0x45,-0x3f),_0x35e99a(-0x109,-0x114)))return _0x1d65c8[_0x53bf2f(-0x60,-0x73)]=_0x4b03f8['omdtT'](_0x3a74cd[_0x35e99a(-0x110,-0xee)](),_0x40164c),_0x2cb7ca;else{const _0x340075=_0xa9294d[_0x35e99a(-0xf1,-0xcf)](_0x56ce73=>_0x4eccb2['has'](_0x56ce73[_0x35e99a(-0x11d,-0x106)])),_0x3e26a4=_0xa9294d[_0x53bf2f(-0x28,-0x4b)](_0x130a3b=>!_0x4eccb2[_0x35e99a(-0xe2,-0xf8)](_0x130a3b[_0x35e99a(-0x11d,-0x110)]));_0x3e26a4[_0x35e99a(-0x128,-0xff)]>0x0&&_0x37dc86['errors'][_0x35e99a(-0x13d,-0x143)](_0x3e26a4['length']+(_0x35e99a(-0x10d,-0x111)+'parent\x20rem'+_0x53bf2f(-0x4d,-0x2f)+_0x35e99a(-0x13a,-0x12d)+_0x35e99a(-0x12b,-0x147))),await this[_0x53bf2f(-0x46,-0x2c)+'s'](_0x340075,_0x32a841,_0x24718c,_0x120e71,_0x37dc86,_0x4eccb2);}}return _0x37dc86[_0x53bf2f(-0x60,-0x40)]=_0x4b03f8[_0x53bf2f(-0x21,-0x3d)](Date[_0x53bf2f(-0x47,-0x75)](),_0x24718c),_0x37dc86;}async[_0x1df448(0x46c,0x493)+'s'](_0x321c94,_0x3afea8,_0x7d4efe,_0x4fe9d8,_0x1fae2d,_0x68168d){const _0x1ff567={'RvuMX':function(_0x5a233f,_0x3b20ba){return _0x5a233f!==_0x3b20ba;},'tqsuF':function(_0x2295ee,_0x3b4a5c,_0x20aa3e){return _0x2295ee(_0x3b4a5c,_0x20aa3e);},'YslMM':function(_0x28b514,_0x28b279){return _0x28b514<_0x28b279;},'ynDHK':_0x3d6d84(0x537,0x55f),'lsqFh':function(_0x1a0c8f,_0x1a1fa1){return _0x1a0c8f-_0x1a1fa1;},'JOQvi':function(_0x33b686,_0x4ac132){return _0x33b686+_0x4ac132;},'xzjGl':_0x87d822(0xaf,0x94),'TuHYy':function(_0x591731,_0x23f430){return _0x591731 instanceof _0x23f430;},'qNXrU':function(_0x422754,_0xb7091e){return _0x422754(_0xb7091e);}};function _0x87d822(_0x2772cb,_0x331b57){return _0x1df448(_0x2772cb,_0x331b57- -0x3fa);}function _0x3d6d84(_0x3427ec,_0x1cb379){return _0x1df448(_0x3427ec,_0x1cb379-0xb2);}for(let _0x507910=0x0;_0x1ff567[_0x3d6d84(0x559,0x56b)](_0x507910,_0x321c94['length']);_0x507910+=_0x3afea8){if(_0x1ff567[_0x87d822(0x94,0xa1)](_0x3d6d84(0x58c,0x55f),_0x1ff567[_0x87d822(0xb6,0xac)]))return this['db']['setSyncSta'+_0x3d6d84(0x4f2,0x519)](_0x2e32e9['id'],null,_0x87d822(0xa6,0x94)),![];else{if(_0x4fe9d8>0x0&&Date['now']()-_0x7d4efe>_0x4fe9d8){const _0x24ed5e=_0x1ff567[_0x87d822(0xa2,0xb4)](_0x321c94['length'],_0x507910);_0x1fae2d[_0x87d822(0x9f,0x93)][_0x3d6d84(0x4fb,0x517)](_0x3d6d84(0x539,0x565)+_0x24ed5e+_0x87d822(0x6f,0x84)),_0x1fae2d[_0x3d6d84(0x52b,0x53c)]+=_0x24ed5e;break;}const _0x352563=_0x321c94[_0x3d6d84(0x537,0x556)](_0x507910,_0x1ff567[_0x87d822(0xac,0x9d)](_0x507910,_0x3afea8));try{const _0x270bed=await this[_0x87d822(0xc6,0x9c)][_0x87d822(0x8f,0x7b)+'riesBatch'](_0x352563[_0x3d6d84(0x51b,0x525)](_0x4e7ad7=>{function _0x3e0927(_0x42759e,_0x1c2598){return _0x87d822(_0x1c2598,_0x42759e-0x3da);}function _0x4d20ec(_0x47a4b5,_0x2e86a9){return _0x87d822(_0x2e86a9,_0x47a4b5-0x421);}const _0x3fcfa9=_0x1ff567['RvuMX'](_0x4e7ad7[_0x4d20ec(0x4e6,0x4bc)+'re'],undefined)?_0x4e7ad7['qualitySco'+'re']:_0x1ff567[_0x3e0927(0x489,0x4a9)](scoreQuality,_0x4e7ad7,QUALITY_LIFECYCLE_CONFIG)[_0x4d20ec(0x48d,0x469)];return{'content':_0x4e7ad7[_0x4d20ec(0x4c4,0x4b3)],'category':mapCategory(_0x4e7ad7[_0x4d20ec(0x4db,0x4f2)]),'tier':mapTier(_0x4e7ad7['tier']),'tags':_0x4e7ad7[_0x4d20ec(0x4c3,0x4e3)],'created_at':_0x4e7ad7[_0x4d20ec(0x4cc,0x4d9)],'parent_id':_0x4e7ad7['parentId']?_0x68168d['get'](_0x4e7ad7['parentId']):undefined,'chunk_index':_0x4e7ad7[_0x3e0927(0x44c,0x454)]??undefined,'chunk_total':_0x4e7ad7[_0x4d20ec(0x4d6,0x4b0)]??undefined,'quality_score':_0x3fcfa9};}));for(let _0xdb2a32=0x0;_0xdb2a32<_0x270bed[_0x3d6d84(0x553,0x554)]['length'];_0xdb2a32++){_0xdb2a32<_0x352563[_0x3d6d84(0x541,0x52c)]&&_0x270bed[_0x3d6d84(0x54c,0x554)][_0xdb2a32]&&(this['db'][_0x87d822(0xd5,0xc0)+_0x3d6d84(0x4f6,0x519)](_0x352563[_0xdb2a32]['id'],_0x270bed['ids'][_0xdb2a32],_0x1ff567[_0x87d822(0x99,0x77)]),_0x68168d[_0x87d822(0x9f,0xb8)](_0x352563[_0xdb2a32]['id'],_0x270bed[_0x3d6d84(0x57b,0x554)][_0xdb2a32]),_0x1fae2d['syncedItem'+'s'][_0x3d6d84(0x4f2,0x517)]({'localId':_0x352563[_0xdb2a32]['id'],'remoteId':_0x270bed[_0x3d6d84(0x546,0x554)][_0xdb2a32]}));}_0x1fae2d['pushed']+=_0x270bed[_0x3d6d84(0x549,0x568)],_0x1fae2d[_0x87d822(0x9d,0x90)]+=_0x270bed[_0x87d822(0x6a,0x90)],_0x270bed[_0x87d822(0x73,0x93)][_0x87d822(0xa8,0x80)]>0x0&&_0x1fae2d[_0x87d822(0x6e,0x93)][_0x3d6d84(0x4ef,0x517)](..._0x270bed[_0x87d822(0xac,0x93)]);}catch(_0xfe24df){_0x1fae2d[_0x87d822(0xa9,0x93)][_0x87d822(0x7f,0x6b)](_0x87d822(0xa0,0xa5)+(_0x1ff567[_0x3d6d84(0x56f,0x569)](_0xfe24df,Error)?_0xfe24df[_0x3d6d84(0x528,0x543)]:_0x1ff567[_0x3d6d84(0x540,0x531)](String,_0xfe24df))),_0x1fae2d[_0x87d822(0x85,0x90)]+=_0x352563[_0x87d822(0x86,0x80)];}}}}async[_0x1df448(0x467,0x480)+_0x2f55fe(0x429,0x455)](){const _0x1c397a={'FzVXB':function(_0x2a5de2,_0x27ada5){return _0x2a5de2 instanceof _0x27ada5;},'hZsus':'404','tNbag':'not\x20found','cURbK':'Not\x20Found','xKAFy':function(_0x36a2a4,_0x3861b7){return _0x36a2a4===_0x3861b7;},'WBSRJ':_0x2b2dd0(0x28b,0x291)},_0x1b30b7=this['db'][_0x2b2dd0(0x28f,0x275)+_0x5ae42d(0x439,0x41f)+'s']();function _0x5ae42d(_0x4c14ce,_0x34b03b){return _0x1df448(_0x34b03b,_0x4c14ce- -0x83);}let _0x296069=0x0;const _0x4af61d=[];for(const _0x4bcc8d of _0x1b30b7){const _0x54c22a=this['db'][_0x2b2dd0(0x282,0x28b)+_0x2b2dd0(0x244,0x25a)](_0x4bcc8d[_0x2b2dd0(0x293,0x2b4)]);if(!_0x54c22a?.['remoteId']){this['db'][_0x2b2dd0(0x24b,0x274)+_0x5ae42d(0x40d,0x437)](_0x4bcc8d[_0x2b2dd0(0x2de,0x2b4)]);continue;}try{await this[_0x5ae42d(0x413,0x412)]['deleteMemo'+'ry'](_0x54c22a[_0x5ae42d(0x43b,0x41b)]),this['db'][_0x2b2dd0(0x288,0x274)+'oneSynced'](_0x4bcc8d[_0x2b2dd0(0x2a6,0x2b4)]),_0x296069++;}catch(_0x61a34b){if('UKTeD'!=='atIsG'){const _0x580553=_0x1c397a['FzVXB'](_0x61a34b,Error)?_0x61a34b[_0x2b2dd0(0x2a8,0x284)]:String(_0x61a34b);if(_0x580553['includes'](_0x1c397a[_0x5ae42d(0x428,0x42e)])||_0x580553[_0x5ae42d(0x40c,0x3f9)](_0x1c397a[_0x2b2dd0(0x29a,0x27b)])||_0x580553[_0x2b2dd0(0x25c,0x282)](_0x1c397a[_0x2b2dd0(0x26a,0x26e)]))this['db'][_0x5ae42d(0x3fe,0x429)+'oneSynced'](_0x4bcc8d[_0x5ae42d(0x43e,0x46a)]),_0x296069++;else{if(_0x1c397a[_0x2b2dd0(0x2ae,0x2b0)](_0x1c397a['WBSRJ'],_0x2b2dd0(0x26b,0x291)))_0x4af61d[_0x5ae42d(0x3e2,0x3d2)](_0x5ae42d(0x3eb,0x3ce)+_0x4bcc8d['memoryId']+_0x5ae42d(0x42d,0x456)+_0x580553);else return _0x3cff8c[_0x649e22]??_0x35ca07;}}else _0x13fe54['set'](_0x356135[_0x2b2dd0(0x286,0x278)],_0x91e294[_0x5ae42d(0x43b,0x441)]);}}function _0x2b2dd0(_0x3e3eaa,_0x57d2ac){return _0x1df448(_0x3e3eaa,_0x57d2ac- -0x20d);}return{'deleted':_0x296069,'errors':_0x4af61d};}[_0x2f55fe(0x42d,0x418)+_0x2f55fe(0x42b,0x41e)](){function _0x580338(_0x2c4271,_0x590405){return _0x1df448(_0x590405,_0x2c4271- -0x651);}function _0x4bf04d(_0x6345c7,_0x318f83){return _0x1df448(_0x6345c7,_0x318f83- -0xf0);}return this['db'][_0x4bf04d(0x3df,0x3bc)+_0x4bf04d(0x3b0,0x399)+'es']()['length'];}}
|
package/dist/sync/scheduler.js
CHANGED
|
@@ -1,140 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sync Scheduler
|
|
3
|
-
*
|
|
4
|
-
* 주기적으로 MemorySynchronizer.sync()를 실행하는 스케줄러.
|
|
5
|
-
* CLI `sync --watch` 또는 라이브러리로 사용 가능.
|
|
6
|
-
*/
|
|
7
|
-
export class SyncScheduler {
|
|
8
|
-
synchronizer;
|
|
9
|
-
options;
|
|
10
|
-
logger;
|
|
11
|
-
timer = null;
|
|
12
|
-
running = false;
|
|
13
|
-
syncing = false;
|
|
14
|
-
syncCount = 0;
|
|
15
|
-
lastSyncAt = null;
|
|
16
|
-
lastResult = null;
|
|
17
|
-
startedAt = null;
|
|
18
|
-
constructor(synchronizer, options, logger) {
|
|
19
|
-
this.synchronizer = synchronizer;
|
|
20
|
-
this.options = options;
|
|
21
|
-
this.logger = logger;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 스케줄러 시작
|
|
25
|
-
*/
|
|
26
|
-
async start() {
|
|
27
|
-
if (this.running) {
|
|
28
|
-
this.logger?.warn('Scheduler already running');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (this.options.intervalMs <= 0) {
|
|
32
|
-
this.logger?.warn('Scheduler disabled (intervalMs <= 0)');
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
this.running = true;
|
|
36
|
-
this.startedAt = new Date();
|
|
37
|
-
this.logger?.info('Scheduler started', { intervalMs: this.options.intervalMs });
|
|
38
|
-
// 시작 시 즉시 sync (기본 동작)
|
|
39
|
-
if (this.options.syncOnStart !== false) {
|
|
40
|
-
await this.tick();
|
|
41
|
-
}
|
|
42
|
-
this.timer = setInterval(() => {
|
|
43
|
-
this.tick().catch((err) => {
|
|
44
|
-
this.logger?.error('Scheduler tick error', err instanceof Error ? err : new Error(String(err)));
|
|
45
|
-
});
|
|
46
|
-
}, this.options.intervalMs);
|
|
47
|
-
// unref: Node.js 프로세스가 타이머 때문에 종료되지 않는 것을 방지
|
|
48
|
-
if (this.timer && typeof this.timer === 'object' && 'unref' in this.timer) {
|
|
49
|
-
this.timer.unref();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* 스케줄러 중지
|
|
54
|
-
*/
|
|
55
|
-
stop() {
|
|
56
|
-
if (!this.running)
|
|
57
|
-
return;
|
|
58
|
-
if (this.timer) {
|
|
59
|
-
clearInterval(this.timer);
|
|
60
|
-
this.timer = null;
|
|
61
|
-
}
|
|
62
|
-
this.running = false;
|
|
63
|
-
this.logger?.info('Scheduler stopped', { syncCount: this.syncCount });
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* 실행 중 여부
|
|
67
|
-
*/
|
|
68
|
-
isRunning() {
|
|
69
|
-
return this.running;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* 현재 sync 중 여부
|
|
73
|
-
*/
|
|
74
|
-
isSyncing() {
|
|
75
|
-
return this.syncing;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 스케줄러 상태
|
|
79
|
-
*/
|
|
80
|
-
getStatus() {
|
|
81
|
-
let nextSyncAt = null;
|
|
82
|
-
if (this.running && this.lastSyncAt) {
|
|
83
|
-
const next = new Date(this.lastSyncAt.getTime() + this.options.intervalMs);
|
|
84
|
-
nextSyncAt = next.toISOString();
|
|
85
|
-
}
|
|
86
|
-
else if (this.running && this.startedAt) {
|
|
87
|
-
const next = new Date(this.startedAt.getTime() + this.options.intervalMs);
|
|
88
|
-
nextSyncAt = next.toISOString();
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
running: this.running,
|
|
92
|
-
syncing: this.syncing,
|
|
93
|
-
syncCount: this.syncCount,
|
|
94
|
-
lastSyncAt: this.lastSyncAt?.toISOString() ?? null,
|
|
95
|
-
lastResult: this.lastResult,
|
|
96
|
-
intervalMs: this.options.intervalMs,
|
|
97
|
-
nextSyncAt,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* 수동으로 즉시 sync 실행 (스케줄러 타이머와 무관)
|
|
102
|
-
*/
|
|
103
|
-
async syncNow() {
|
|
104
|
-
return this.tick();
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* 한 번의 sync 사이클
|
|
108
|
-
*/
|
|
109
|
-
async tick() {
|
|
110
|
-
if (this.syncing) {
|
|
111
|
-
this.logger?.debug('Sync already in progress, skipping');
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
this.syncing = true;
|
|
115
|
-
try {
|
|
116
|
-
const result = await this.synchronizer.sync();
|
|
117
|
-
this.syncCount++;
|
|
118
|
-
this.lastSyncAt = new Date();
|
|
119
|
-
this.lastResult = result;
|
|
120
|
-
this.logger?.info('Sync completed', {
|
|
121
|
-
pushed: result.pushed,
|
|
122
|
-
pulled: result.pulled,
|
|
123
|
-
errors: result.errors.length,
|
|
124
|
-
duration: result.duration,
|
|
125
|
-
});
|
|
126
|
-
this.options.onSync?.(result);
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
131
|
-
this.logger?.error('Sync failed', err);
|
|
132
|
-
this.options.onError?.(err);
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
finally {
|
|
136
|
-
this.syncing = false;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=scheduler.js.map
|
|
1
|
+
function _0x4c447d(_0xa68cfa,_0x2fd726){return _0x1b80(_0xa68cfa- -0x373,_0x2fd726);}function _0x23e7(){const _0xca77e2=['DuXsC0O','CNvUBMLUzW','vwzQDfC','Aw5MBW','Bg9Nz2vY','svDUD2C','B25tEw5J','Dw5Yzwy','u3LUyYbMywLSzq','Aw50zxj2ywXnCW','mZq0sKfKyvrN','u2nOzwr1BgvYia','zxrLza','ChvSBgvK','C3LUy0nVDw50','BgfZDfjLC3vSDa','u3LUyYbJB21WBa','C3rHCNrLzef0','C3LUy05VDW','mJfZqK94Eui','mteZnujWvNL3Ea','CgLUzW','mteWmZy0nhLTAeHqqW','BgvUz3rO','C3LUy2LUzW','zhvYyxrPB24','mtCWodGZnJbZqxzTzg0','AxnsDw5UAw5N','CK5qu0y','AKzOu1O','C3rVCa','mZGZmZuXne9NzgzcDG','z2v0vgLTzq','C3LUyW','mZCXmdy4DMHiwvLh','veHXv0S','zhKGAw4GChjVzW','zxjYB3jZ','C3rHCNq','mtq3nJHuvw9wzLi','uwnlveS','mJeWnZyYEKTRuuT1','EfbmBhi','C3rVChbLza','B2jQzwn0','B25fCNjVCG','D2fYBG','mZKZnZi2ovjIrNjdCW','DgLTzxi','BgfZDfn5BMnbDa','DgLJAW','idW9idaP','AxntEw5JAw5N','qwHIELm','DgLJAYbLCNjVCG','Dg9ju09tDhjPBG','ChvZAgvK','C3rHCNrLza','B3b0Aw9UCW','C3LUy2HYB25PEG','BxDZAgO','zgvIDwC','u3LUyYbHBhjLyq','z2v0u3rHDhvZ','EePqu0G'];_0x23e7=function(){return _0xca77e2;};return _0x23e7();}function _0x47a343(_0x28d1b6,_0x2ac11a){return _0x1b80(_0x2ac11a-0x394,_0x28d1b6);}(function(_0x3de67b,_0x41a1ad){function _0xaf2414(_0x48187f,_0x368bec){return _0x1b80(_0x368bec- -0x20e,_0x48187f);}const _0x7e0d9e=_0x3de67b();function _0x38907b(_0x2adce8,_0xc8c373){return _0x1b80(_0x2adce8- -0x9f,_0xc8c373);}while(!![]){try{const _0xc25e46=-parseInt(_0xaf2414(-0xfc,-0xe4))/0x1+parseInt(_0x38907b(0x97,0x96))/0x2*(-parseInt(_0x38907b(0x88,0x8f))/0x3)+-parseInt(_0xaf2414(-0xd3,-0xd3))/0x4*(parseInt(_0x38907b(0x89,0x8f))/0x5)+parseInt(_0xaf2414(-0xf9,-0xdb))/0x6+parseInt(_0x38907b(0x63,0x5d))/0x7+parseInt(_0x38907b(0x7f,0x7b))/0x8*(parseInt(_0x38907b(0x9e,0x99))/0x9)+parseInt(_0x38907b(0x8f,0x88))/0xa;if(_0xc25e46===_0x41a1ad)break;else _0x7e0d9e['push'](_0x7e0d9e['shift']());}catch(_0x4c494f){_0x7e0d9e['push'](_0x7e0d9e['shift']());}}}(_0x23e7,0xa537a));function _0x1b80(_0x3b64a9,_0x54ccc4){_0x3b64a9=_0x3b64a9-0x100;const _0x23e7ef=_0x23e7();let _0x1b8023=_0x23e7ef[_0x3b64a9];if(_0x1b80['WDjLrR']===undefined){var _0x1de3c2=function(_0x2f9276){const _0x15b2b4='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4215ec='',_0x3e3dcc='';for(let _0x185c3e=0x0,_0x5aee6c,_0x19281b,_0x3008e7=0x0;_0x19281b=_0x2f9276['charAt'](_0x3008e7++);~_0x19281b&&(_0x5aee6c=_0x185c3e%0x4?_0x5aee6c*0x40+_0x19281b:_0x19281b,_0x185c3e++%0x4)?_0x4215ec+=String['fromCharCode'](0xff&_0x5aee6c>>(-0x2*_0x185c3e&0x6)):0x0){_0x19281b=_0x15b2b4['indexOf'](_0x19281b);}for(let _0x13250a=0x0,_0x594f5c=_0x4215ec['length'];_0x13250a<_0x594f5c;_0x13250a++){_0x3e3dcc+='%'+('00'+_0x4215ec['charCodeAt'](_0x13250a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3e3dcc);};_0x1b80['CSStwd']=_0x1de3c2,_0x1b80['pypadI']={},_0x1b80['WDjLrR']=!![];}const _0x3a099d=_0x23e7ef[0x0],_0x37b0d5=_0x3b64a9+_0x3a099d,_0x1b8b47=_0x1b80['pypadI'][_0x37b0d5];return!_0x1b8b47?(_0x1b8023=_0x1b80['CSStwd'](_0x1b8023),_0x1b80['pypadI'][_0x37b0d5]=_0x1b8023):_0x1b8023=_0x1b8b47,_0x1b8023;}export class SyncScheduler{['synchroniz'+'er'];['options'];['logger'];['timer']=null;[_0x47a343(0x4b3,0x4a9)]=![];['syncing']=![];[_0x4c447d(-0x251,-0x26b)]=0x0;[_0x47a343(0x4a9,0x498)]=null;['lastResult']=null;[_0x47a343(0x4c6,0x4b9)]=null;constructor(_0x4e667a,_0x20b397,_0x4fe5f8){function _0x55c736(_0x4dd6b6,_0x2f420b){return _0x4c447d(_0x4dd6b6-0x457,_0x2f420b);}this[_0x55c736(0x1f2,0x1fb)+'er']=_0x4e667a,this[_0x55c736(0x1f1,0x1fe)]=_0x20b397;function _0x1e32f5(_0x3dc870,_0x27f027){return _0x4c447d(_0x27f027-0x24b,_0x3dc870);}this['logger']=_0x4fe5f8;}async[_0x4c447d(-0x239,-0x24e)](){const _0x3d89a6={'XzJAQ':function(_0x496658,_0x1f03aa){return _0x496658+_0x1f03aa;},'mwshj':function(_0x3a2c28,_0x27bf05){return _0x3a2c28 instanceof _0x27bf05;},'AhbzS':function(_0x212430,_0x5dd3cc){return _0x212430===_0x5dd3cc;},'kAchW':_0x24fe08(0x289,0x286),'THqWK':_0x24fe08(0x28f,0x27e)+'disabled\x20('+_0x24fe08(0x28d,0x281)+_0x5a109b(0xc6,0xb1),'EHOsd':_0x24fe08(0x28f,0x297)+_0x5a109b(0xcc,0xe1),'QcKTK':function(_0x4a781f,_0xedf89f){return _0x4a781f!==_0xedf89f;},'ERgmT':_0x5a109b(0x100,0xf1)};if(this[_0x5a109b(0xd5,0xe3)]){if(_0x5a109b(0xfe,0xee)===_0x24fe08(0x2ae,0x291)){this[_0x5a109b(0xd8,0xba)]?.[_0x5a109b(0xc1,0xa7)](_0x24fe08(0x28f,0x285)+'already\x20ru'+'nning');return;}else{let _0x5681a1=null;if(this[_0x24fe08(0x285,0x2a1)]&&this[_0x5a109b(0xc4,0xb1)]){const _0x1a1768=new _0x58ea33(_0x3d89a6['XzJAQ'](this[_0x5a109b(0xc4,0xc9)][_0x5a109b(0xf4,0xfa)](),this['options'][_0x5a109b(0xdd,0xfd)]));_0x5681a1=_0x1a1768['toISOStrin'+'g']();}else{if(this['running']&&this['startedAt']){const _0x29fa94=new _0x4f082d(this[_0x5a109b(0xe5,0x100)][_0x24fe08(0x2a4,0x2c4)]()+this[_0x24fe08(0x27d,0x299)][_0x24fe08(0x28d,0x28c)]);_0x5681a1=_0x29fa94[_0x5a109b(0xca,0xe6)+'g']();}}return{'running':this[_0x24fe08(0x285,0x281)],'syncing':this[_0x24fe08(0x29c,0x2af)],'syncCount':this[_0x5a109b(0xe2,0xed)],'lastSyncAt':this['lastSyncAt']?.[_0x24fe08(0x27a,0x260)+'g']()??null,'lastResult':this[_0x5a109b(0xe3,0xd9)],'intervalMs':this[_0x5a109b(0xcd,0xd1)]['intervalMs'],'nextSyncAt':_0x5681a1};}}function _0x24fe08(_0x4319e6,_0x455a4a){return _0x4c447d(_0x4319e6-0x4e3,_0x455a4a);}if(this[_0x24fe08(0x27d,0x275)][_0x24fe08(0x28d,0x274)]<=0x0){if(_0x3d89a6[_0x24fe08(0x278,0x281)](_0x24fe08(0x289,0x26d),_0x3d89a6['kAchW'])){this[_0x24fe08(0x288,0x27e)]?.[_0x24fe08(0x271,0x26d)](_0x3d89a6[_0x5a109b(0xf7,0x106)]);return;}else return this['running'];}function _0x5a109b(_0x4d64f3,_0x5425e1){return _0x4c447d(_0x4d64f3-0x333,_0x5425e1);}this['running']=!![],this['startedAt']=new Date(),this[_0x5a109b(0xd8,0xca)]?.[_0x24fe08(0x287,0x28d)](_0x3d89a6['EHOsd'],{'intervalMs':this[_0x24fe08(0x27d,0x288)][_0x5a109b(0xdd,0xf7)]}),_0x3d89a6[_0x24fe08(0x2ac,0x2ac)](this['options']['syncOnStar'+'t'],![])&&await this[_0x5a109b(0xc5,0xa6)](),this[_0x24fe08(0x273,0x285)]=setInterval(()=>{const _0x7a1730={'uLRsJ':function(_0x2b562d,_0x47fc30){function _0x31a458(_0x4da005,_0x4130b7){return _0x1b80(_0x4da005- -0xdd,_0x4130b7);}return _0x3d89a6[_0x31a458(0x32,0x34)](_0x2b562d,_0x47fc30);}};function _0x3c28c5(_0x245ed6,_0x5bab34){return _0x5a109b(_0x245ed6- -0x97,_0x5bab34);}this[_0x3c28c5(0x2e,0x35)]()['catch'](_0x138c8b=>{function _0x425cbe(_0x4285d0,_0x41edbf){return _0x3c28c5(_0x4285d0- -0x2b3,_0x41edbf);}function _0xb4a2b(_0x220324,_0xf2bd83){return _0x3c28c5(_0xf2bd83-0x3e9,_0x220324);}this[_0x425cbe(-0x272,-0x28c)]?.['error'](_0x425cbe(-0x26b,-0x252)+_0x425cbe(-0x281,-0x264),_0x7a1730[_0xb4a2b(0x425,0x426)](_0x138c8b,Error)?_0x138c8b:new Error(String(_0x138c8b)));});},this[_0x5a109b(0xcd,0xc1)]['intervalMs']),this[_0x24fe08(0x273,0x26d)]&&typeof this[_0x5a109b(0xc3,0xda)]===_0x3d89a6['ERgmT']&&_0x5a109b(0xdb,0xfa)in this[_0x24fe08(0x273,0x25a)]&&(_0x24fe08(0x2a1,0x292)==='bRHGZ'?this['timer']['unref']():this[_0x24fe08(0x273,0x255)][_0x24fe08(0x28b,0x2a7)]());}[_0x4c447d(-0x241,-0x240)](){function _0x266139(_0x4226e3,_0x39f4aa){return _0x4c447d(_0x4226e3-0x64b,_0x39f4aa);}function _0x24d469(_0x51b0ab,_0x1411d6){return _0x4c447d(_0x1411d6-0x32c,_0x51b0ab);}if(!this[_0x24d469(0xb2,0xce)])return;this[_0x266139(0x3db,0x3d7)]&&(clearInterval(this[_0x266139(0x3db,0x3bf)]),this['timer']=null),this[_0x24d469(0xc4,0xce)]=![],this[_0x266139(0x3f0,0x3d5)]?.[_0x266139(0x3ef,0x3ef)](_0x266139(0x3f7,0x402)+_0x24d469(0xfd,0xf8),{'syncCount':this[_0x24d469(0xc5,0xdb)]});}[_0x4c447d(-0x244,-0x259)](){return this['running'];}[_0x47a343(0x489,0x49b)](){function _0x3439f(_0x4cce0f,_0x2d7753){return _0x47a343(_0x2d7753,_0x4cce0f- -0x8);}return this[_0x3439f(0x4b8,0x4c1)];}[_0x4c447d(-0x261,-0x24f)](){function _0x502c08(_0x27fcf1,_0x5d9d00){return _0x47a343(_0x27fcf1,_0x5d9d00- -0x236);}const _0x37c39f={'rNPSF':function(_0xab17af,_0x6467aa){return _0xab17af+_0x6467aa;}};let _0x48a09f=null;if(this[_0x502c08(0x266,0x273)]&&this['lastSyncAt']){const _0xa9ecab=new Date(this['lastSyncAt']['getTime']()+this[_0x24fdf8(-0x191,-0x194)][_0x24fdf8(-0x175,-0x184)]);_0x48a09f=_0xa9ecab[_0x502c08(0x24c,0x268)+'g']();}else{if(this['running']&&this['startedAt']){const _0x29457e=new Date(_0x37c39f[_0x502c08(0x2ad,0x28e)](this[_0x502c08(0x262,0x283)]['getTime'](),this['options'][_0x502c08(0x262,0x27b)]));_0x48a09f=_0x29457e['toISOStrin'+'g']();}}function _0x24fdf8(_0x2323f4,_0x47ebdf){return _0x47a343(_0x2323f4,_0x47ebdf- -0x635);}return{'running':this[_0x24fdf8(-0x180,-0x18c)],'syncing':this[_0x502c08(0x294,0x28a)],'syncCount':this['syncCount'],'lastSyncAt':this[_0x502c08(0x265,0x262)]?.[_0x502c08(0x24a,0x268)+'g']()??null,'lastResult':this[_0x24fdf8(-0x183,-0x17e)],'intervalMs':this['options'][_0x502c08(0x28e,0x27b)],'nextSyncAt':_0x48a09f};}async[_0x47a343(0x4d6,0x4ba)](){function _0x333b48(_0x2613c5,_0x2426f7){return _0x4c447d(_0x2613c5-0x466,_0x2426f7);}return this[_0x333b48(0x1f8,0x1e9)]();}async['tick'](){const _0x11ea28={'xJPSH':function(_0x6cd136,_0x1abe35){return _0x6cd136 instanceof _0x1abe35;},'UfjtW':_0x1ce981(-0x24e,-0x240)+'d'};if(this['syncing'])return this[_0x1ce981(-0x238,-0x244)]?.[_0x1d5e8d(0x352,0x367)](_0x1ce981(-0x252,-0x24b)+_0x1d5e8d(0x37a,0x376)+'ress,\x20skip'+_0x1ce981(-0x216,-0x233)),null;function _0x1ce981(_0x43673e,_0x5bef87){return _0x47a343(_0x43673e,_0x5bef87- -0x6f0);}function _0x1d5e8d(_0x34f8cc,_0x5bf1ea){return _0x47a343(_0x5bf1ea,_0x34f8cc- -0x152);}this['syncing']=!![];try{const _0x377a8e=await this[_0x1d5e8d(0x350,0x336)+'er'][_0x1ce981(-0x210,-0x227)]();return this[_0x1d5e8d(0x364,0x37f)]++,this[_0x1d5e8d(0x346,0x35c)]=new Date(),this[_0x1d5e8d(0x365,0x375)]=_0x377a8e,this[_0x1d5e8d(0x35a,0x34d)]?.[_0x1ce981(-0x25d,-0x245)](_0x1d5e8d(0x366,0x379)+_0x1ce981(-0x23f,-0x23c),{'pushed':_0x377a8e[_0x1d5e8d(0x34d,0x336)],'pulled':_0x377a8e[_0x1ce981(-0x224,-0x23b)],'errors':_0x377a8e[_0x1ce981(-0x206,-0x223)][_0x1ce981(-0x248,-0x231)],'duration':_0x377a8e[_0x1d5e8d(0x36f,0x390)]}),this[_0x1ce981(-0x25f,-0x24f)][_0x1ce981(-0x22e,-0x242)]?.(_0x377a8e),_0x377a8e;}catch(_0x4c34ea){const _0x3aa961=_0x11ea28[_0x1ce981(-0x243,-0x249)](_0x4c34ea,Error)?_0x4c34ea:new Error(String(_0x4c34ea));return this[_0x1ce981(-0x25f,-0x244)]?.['error'](_0x11ea28[_0x1ce981(-0x252,-0x246)],_0x3aa961),this[_0x1ce981(-0x24b,-0x24f)][_0x1ce981(-0x24c,-0x25c)]?.(_0x3aa961),null;}finally{this['syncing']=![];}}}
|