tanksync 1.0.0 → 1.0.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.
Files changed (42) hide show
  1. package/README.md +2 -2
  2. package/dist/config.d.ts +26 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +102 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/errors.d.ts +54 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +143 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +54 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +151 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/logger.d.ts +14 -0
  15. package/dist/logger.d.ts.map +1 -0
  16. package/dist/logger.js +45 -0
  17. package/dist/logger.js.map +1 -0
  18. package/dist/payload-cache.d.ts +49 -0
  19. package/dist/payload-cache.d.ts.map +1 -0
  20. package/dist/payload-cache.js +146 -0
  21. package/dist/payload-cache.js.map +1 -0
  22. package/dist/payload-downloader.d.ts +21 -0
  23. package/dist/payload-downloader.d.ts.map +1 -0
  24. package/dist/payload-downloader.js +103 -0
  25. package/dist/payload-downloader.js.map +1 -0
  26. package/dist/payload-verifier.d.ts +26 -0
  27. package/dist/payload-verifier.d.ts.map +1 -0
  28. package/dist/payload-verifier.js +95 -0
  29. package/dist/payload-verifier.js.map +1 -0
  30. package/dist/payload-worker.d.ts +49 -0
  31. package/dist/payload-worker.d.ts.map +1 -0
  32. package/dist/payload-worker.js +213 -0
  33. package/dist/payload-worker.js.map +1 -0
  34. package/dist/protocol.d.ts +44 -0
  35. package/dist/protocol.d.ts.map +1 -0
  36. package/dist/protocol.js +117 -0
  37. package/dist/protocol.js.map +1 -0
  38. package/dist/types.d.ts +77 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +6 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +6 -2
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * TankSync Payload Worker
4
+ * Manages child process lifecycle and IPC communication
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PayloadWorker = void 0;
8
+ const child_process_1 = require("child_process");
9
+ const protocol_1 = require("./protocol");
10
+ const errors_1 = require("./errors");
11
+ class PayloadWorker {
12
+ constructor(logger, payloadPath, requestTimeout) {
13
+ this.process = null;
14
+ this.isReady = false;
15
+ this.pendingRequests = new Map();
16
+ this.lineBuffer = '';
17
+ this.logger = logger;
18
+ this.payloadPath = payloadPath;
19
+ this.requestTimeout = requestTimeout;
20
+ }
21
+ /**
22
+ * Start worker process and wait for ready signal
23
+ */
24
+ async start(handshakeTimeout = 5000) {
25
+ this.logger.info('Starting payload worker process');
26
+ return new Promise((resolve, reject) => {
27
+ try {
28
+ this.process = (0, child_process_1.spawn)('node', [this.payloadPath], {
29
+ stdio: ['pipe', 'pipe', 'pipe'],
30
+ timeout: handshakeTimeout,
31
+ });
32
+ if (!this.process) {
33
+ throw new errors_1.WorkerStartupError('Failed to spawn child process');
34
+ }
35
+ const handshakeTimer = setTimeout(() => {
36
+ this.process?.kill();
37
+ this.process = null;
38
+ reject(new errors_1.WorkerHandshakeTimeoutError(handshakeTimeout));
39
+ }, handshakeTimeout);
40
+ this.setupProcessHandlers();
41
+ // Listen for ready signal
42
+ this.process.stdout.once('data', (data) => {
43
+ this.lineBuffer = data.toString();
44
+ try {
45
+ const message = protocol_1.Protocol.parse(this.lineBuffer);
46
+ if (protocol_1.Protocol.isReady(message)) {
47
+ clearTimeout(handshakeTimer);
48
+ this.isReady = true;
49
+ this.logger.info('Worker ready, version:', message.version);
50
+ resolve();
51
+ }
52
+ }
53
+ catch (error) {
54
+ clearTimeout(handshakeTimer);
55
+ reject(new errors_1.WorkerStartupError(`Failed to parse ready signal: ${error}`));
56
+ }
57
+ });
58
+ }
59
+ catch (error) {
60
+ reject(new errors_1.WorkerStartupError(`Failed to start worker: ${error}`));
61
+ }
62
+ });
63
+ }
64
+ /**
65
+ * Send purchase request to worker
66
+ */
67
+ async purchaseItem(request) {
68
+ if (!this.isReady || !this.process) {
69
+ throw new errors_1.WorkerUnavailableError('Worker is not ready');
70
+ }
71
+ const ipcRequest = protocol_1.Protocol.createPurchaseRequest(request);
72
+ return this.sendRequest(ipcRequest);
73
+ }
74
+ /**
75
+ * Send generic request to worker
76
+ */
77
+ async sendRequest(request) {
78
+ if (!this.isReady || !this.process) {
79
+ throw new errors_1.WorkerUnavailableError('Worker is not ready');
80
+ }
81
+ return new Promise((resolve, reject) => {
82
+ const timeout = setTimeout(() => {
83
+ this.pendingRequests.delete(request.id);
84
+ reject(new errors_1.RequestTimeoutError(request.id, this.requestTimeout));
85
+ }, this.requestTimeout);
86
+ this.pendingRequests.set(request.id, {
87
+ resolve,
88
+ reject,
89
+ timeout,
90
+ timestamp: Date.now(),
91
+ });
92
+ try {
93
+ const message = protocol_1.Protocol.serialize(request);
94
+ this.process.stdin.write(message + '\n');
95
+ this.logger.debug('Request sent:', request.id);
96
+ }
97
+ catch (error) {
98
+ this.pendingRequests.delete(request.id);
99
+ clearTimeout(timeout);
100
+ reject(new Error(`Failed to send request: ${error}`));
101
+ }
102
+ });
103
+ }
104
+ /**
105
+ * Setup process event handlers
106
+ */
107
+ setupProcessHandlers() {
108
+ if (!this.process)
109
+ return;
110
+ // Handle stdout (regular messages)
111
+ this.process.stdout.on('data', (data) => {
112
+ this.lineBuffer += data.toString();
113
+ const lines = this.lineBuffer.split('\n');
114
+ this.lineBuffer = lines.pop() || ''; // Keep incomplete line
115
+ for (const line of lines) {
116
+ if (line.trim()) {
117
+ try {
118
+ const message = protocol_1.Protocol.parse(line);
119
+ this.handleMessage(message);
120
+ }
121
+ catch (error) {
122
+ this.logger.error('Failed to parse message:', error);
123
+ }
124
+ }
125
+ }
126
+ });
127
+ // Handle stderr (logging/errors)
128
+ this.process.stderr.on('data', (data) => {
129
+ this.logger.warn('Worker stderr:', data.toString());
130
+ });
131
+ // Handle process exit
132
+ this.process.on('exit', (code, signal) => {
133
+ this.logger.warn('Worker process exited', { code, signal });
134
+ this.isReady = false;
135
+ this.process = null;
136
+ // Reject all pending requests
137
+ this.pendingRequests.forEach(({ reject, timeout }) => {
138
+ clearTimeout(timeout);
139
+ reject(new errors_1.WorkerCrashError(code, signal));
140
+ });
141
+ this.pendingRequests.clear();
142
+ });
143
+ // Handle process error
144
+ this.process.on('error', (error) => {
145
+ this.logger.error('Worker process error:', error);
146
+ this.isReady = false;
147
+ // Reject all pending requests
148
+ this.pendingRequests.forEach(({ reject, timeout }) => {
149
+ clearTimeout(timeout);
150
+ reject(error);
151
+ });
152
+ this.pendingRequests.clear();
153
+ });
154
+ }
155
+ /**
156
+ * Handle message from worker
157
+ */
158
+ handleMessage(message) {
159
+ if (!message.id) {
160
+ this.logger.warn('Received message without ID');
161
+ return;
162
+ }
163
+ const pending = this.pendingRequests.get(message.id);
164
+ if (!pending) {
165
+ this.logger.debug('Received message for unknown request:', message.id);
166
+ return;
167
+ }
168
+ this.pendingRequests.delete(message.id);
169
+ clearTimeout(pending.timeout);
170
+ if (protocol_1.Protocol.isSuccess(message)) {
171
+ this.logger.debug('Request succeeded:', message.id);
172
+ pending.resolve(message.result);
173
+ }
174
+ else {
175
+ const errorMessage = protocol_1.Protocol.getErrorMessage(message);
176
+ this.logger.debug(`Request failed: ${message.id} - ${errorMessage}`);
177
+ pending.reject(new Error(errorMessage));
178
+ }
179
+ }
180
+ /**
181
+ * Gracefully shutdown worker
182
+ */
183
+ async shutdown(timeout = 5000) {
184
+ if (!this.process) {
185
+ return;
186
+ }
187
+ const process = this.process;
188
+ return new Promise((resolve) => {
189
+ const timer = setTimeout(() => {
190
+ this.logger.warn('Worker shutdown timeout, forcefully killing');
191
+ process.kill('SIGKILL');
192
+ }, timeout);
193
+ process.on('exit', () => {
194
+ clearTimeout(timer);
195
+ resolve();
196
+ });
197
+ this.logger.info('Shutting down worker gracefully');
198
+ process.kill('SIGTERM');
199
+ });
200
+ }
201
+ /**
202
+ * Check if worker is ready
203
+ */
204
+ getStatus() {
205
+ return {
206
+ isReady: this.isReady,
207
+ isAlive: !!this.process && !this.process.killed,
208
+ pendingRequests: this.pendingRequests.size,
209
+ };
210
+ }
211
+ }
212
+ exports.PayloadWorker = PayloadWorker;
213
+ //# sourceMappingURL=payload-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload-worker.js","sourceRoot":"","sources":["../src/payload-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * TankSync IPC Protocol
3
+ * JSON-based communication between parent and child process
4
+ */
5
+ import { IPCMessage, IPCRequest, IPCResponse, IPCReadyMessage, PurchaseRequest } from './types';
6
+ export declare class Protocol {
7
+ /**
8
+ * Create a purchase request message
9
+ */
10
+ static createPurchaseRequest(params: PurchaseRequest): IPCRequest;
11
+ /**
12
+ * Create a generic IPC request
13
+ */
14
+ static createRequest(method: string, params: unknown): IPCRequest;
15
+ /**
16
+ * Serialize message to JSON string
17
+ */
18
+ static serialize(message: IPCMessage): string;
19
+ /**
20
+ * Parse message from JSON string
21
+ */
22
+ static parse(data: string): IPCMessage;
23
+ /**
24
+ * Validate IPC message structure
25
+ */
26
+ private static validate;
27
+ /**
28
+ * Check if message is a ready signal
29
+ */
30
+ static isReady(message: IPCMessage): message is IPCReadyMessage;
31
+ /**
32
+ * Check if message is a response
33
+ */
34
+ static isResponse(message: IPCMessage): message is IPCResponse;
35
+ /**
36
+ * Check if response indicates success
37
+ */
38
+ static isSuccess(message: IPCMessage): boolean;
39
+ /**
40
+ * Extract error message from response
41
+ */
42
+ static getErrorMessage(message: IPCMessage): string;
43
+ }
44
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,UAAU,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB,qBAAa,QAAQ;IACnB;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,UAAU;IASjE;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU;IASjE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IAQ7C;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAatC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IA2BvB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,IAAI,eAAe;IAI/D;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,IAAI,WAAW;IAI9D;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IAI9C;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;CASpD"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ /**
3
+ * TankSync IPC Protocol
4
+ * JSON-based communication between parent and child process
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Protocol = void 0;
8
+ const uuid_1 = require("uuid");
9
+ const errors_1 = require("./errors");
10
+ class Protocol {
11
+ /**
12
+ * Create a purchase request message
13
+ */
14
+ static createPurchaseRequest(params) {
15
+ return {
16
+ id: (0, uuid_1.v4)(),
17
+ method: 'purchaseItem',
18
+ params,
19
+ timestamp: Date.now(),
20
+ };
21
+ }
22
+ /**
23
+ * Create a generic IPC request
24
+ */
25
+ static createRequest(method, params) {
26
+ return {
27
+ id: (0, uuid_1.v4)(),
28
+ method,
29
+ params,
30
+ timestamp: Date.now(),
31
+ };
32
+ }
33
+ /**
34
+ * Serialize message to JSON string
35
+ */
36
+ static serialize(message) {
37
+ try {
38
+ return JSON.stringify(message);
39
+ }
40
+ catch (error) {
41
+ throw new Error(`Failed to serialize IPC message: ${error}`);
42
+ }
43
+ }
44
+ /**
45
+ * Parse message from JSON string
46
+ */
47
+ static parse(data) {
48
+ try {
49
+ const message = JSON.parse(data);
50
+ this.validate(message);
51
+ return message;
52
+ }
53
+ catch (error) {
54
+ if (error instanceof errors_1.MalformedResponseError) {
55
+ throw error;
56
+ }
57
+ throw new errors_1.MalformedResponseError(`Failed to parse JSON: ${error}`);
58
+ }
59
+ }
60
+ /**
61
+ * Validate IPC message structure
62
+ */
63
+ static validate(message) {
64
+ if (!message || typeof message !== 'object') {
65
+ throw new errors_1.MalformedResponseError('Message must be a JSON object');
66
+ }
67
+ const msg = message;
68
+ // Check for required fields based on message type
69
+ if (!msg.id || typeof msg.id !== 'string') {
70
+ throw new errors_1.MalformedResponseError('Message must have string id field');
71
+ }
72
+ // Ready message
73
+ if (msg.type === 'ready') {
74
+ if (!msg.version || typeof msg.version !== 'string') {
75
+ throw new errors_1.MalformedResponseError('Ready message must have string version');
76
+ }
77
+ }
78
+ // Response message
79
+ if (msg.success !== undefined) {
80
+ if (typeof msg.success !== 'boolean') {
81
+ throw new errors_1.MalformedResponseError('success field must be boolean');
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Check if message is a ready signal
87
+ */
88
+ static isReady(message) {
89
+ return message.type === 'ready';
90
+ }
91
+ /**
92
+ * Check if message is a response
93
+ */
94
+ static isResponse(message) {
95
+ return message.success !== undefined;
96
+ }
97
+ /**
98
+ * Check if response indicates success
99
+ */
100
+ static isSuccess(message) {
101
+ return message.success === true;
102
+ }
103
+ /**
104
+ * Extract error message from response
105
+ */
106
+ static getErrorMessage(message) {
107
+ if (typeof message.error === 'string') {
108
+ return message.error;
109
+ }
110
+ if (typeof message.message === 'string') {
111
+ return message.message;
112
+ }
113
+ return 'Unknown error';
114
+ }
115
+ }
116
+ exports.Protocol = Protocol;
117
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * TankSync Type Definitions
3
+ */
4
+ export interface ClientConfig {
5
+ payloadUrl?: string;
6
+ payloadVersion?: string;
7
+ payloadSignature?: string;
8
+ cacheDir?: string;
9
+ downloadTimeout?: number;
10
+ requestTimeout?: number;
11
+ maxPayloadSize?: number;
12
+ logLevel?: LogLevel;
13
+ }
14
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
15
+ export interface PurchaseRequest {
16
+ playerId: string;
17
+ itemId: string;
18
+ quantity: number;
19
+ requestId: string;
20
+ }
21
+ export interface PurchaseResult {
22
+ success: boolean;
23
+ transactionId?: string;
24
+ itemId?: string;
25
+ quantity?: number;
26
+ playerId?: string;
27
+ error?: string;
28
+ message?: string;
29
+ }
30
+ export interface IPCMessage {
31
+ id: string;
32
+ method?: string;
33
+ type?: string;
34
+ params?: unknown;
35
+ timestamp?: number;
36
+ success?: boolean;
37
+ result?: unknown;
38
+ error?: string;
39
+ message?: string;
40
+ version?: string;
41
+ }
42
+ export interface IPCRequest extends IPCMessage {
43
+ id: string;
44
+ method: string;
45
+ params: unknown;
46
+ timestamp: number;
47
+ }
48
+ export interface IPCResponse extends IPCMessage {
49
+ id: string;
50
+ success: boolean;
51
+ result?: unknown;
52
+ error?: string;
53
+ }
54
+ export interface IPCReadyMessage extends IPCMessage {
55
+ type: 'ready';
56
+ version: string;
57
+ }
58
+ export interface PayloadMetadata {
59
+ version: string;
60
+ signature: string;
61
+ downloadedAt: number;
62
+ verifiedAt: number;
63
+ }
64
+ export interface PayloadInfo {
65
+ path: string;
66
+ version: string;
67
+ signature: string;
68
+ metadata: PayloadMetadata;
69
+ }
70
+ export interface PendingRequest {
71
+ resolve: (value: any) => void;
72
+ reject: (reason?: any) => void;
73
+ timeout: NodeJS.Timeout;
74
+ timestamp: number;
75
+ }
76
+ export type RequestMap = Map<string, PendingRequest>;
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAG3D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAGD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * TankSync Type Definitions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tanksync",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Production-ready Node.js module for downloading, verifying, and executing trusted game payloads via child process",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -48,6 +48,7 @@
48
48
  "devDependencies": {
49
49
  "@types/jest": "^29.5.0",
50
50
  "@types/node": "^20.0.0",
51
+ "@types/uuid": "^9.0.0",
51
52
  "@typescript-eslint/eslint-plugin": "^6.0.0",
52
53
  "@typescript-eslint/parser": "^6.0.0",
53
54
  "eslint": "^8.0.0",
@@ -56,6 +57,9 @@
56
57
  "typescript": "^5.0.0"
57
58
  },
58
59
  "dependencies": {
59
- "uuid": "^9.0.0"
60
+ "uuid": "^11.1.1"
61
+ },
62
+ "overrides": {
63
+ "minimatch": "^9.0.7"
60
64
  }
61
65
  }