@redjay/threads-json-storage 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/JsonFileStore.d.ts +83 -0
- package/dist/JsonFileStore.d.ts.map +1 -0
- package/dist/JsonFileStore.js +579 -0
- package/dist/JsonFileStore.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joshua Ramirez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @redjay/threads-json-storage
|
|
2
|
+
|
|
3
|
+
JSON file storage adapter for the Threads platform. Stores all data in a local JSON file.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @redjay/threads-json-storage
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { JsonStorageAdapter } from '@redjay/threads-json-storage';
|
|
15
|
+
|
|
16
|
+
const storage = new JsonStorageAdapter({
|
|
17
|
+
filePath: '~/.threads/threads.json'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Use storage adapter
|
|
21
|
+
const threads = await storage.getAllThreads();
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Local file-based storage
|
|
27
|
+
- Automatic backup before writes
|
|
28
|
+
- Human-readable JSON format
|
|
29
|
+
- No external dependencies
|
|
30
|
+
|
|
31
|
+
## Default Location
|
|
32
|
+
|
|
33
|
+
Data is stored at `~/.threads/threads.json` by default.
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
MIT
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ThreadsData, Thread, Group, Container, Entity } from '@redjay/threads-core';
|
|
2
|
+
import { IFileThreadStore, IStorageClient, ThreadFilter, ContainerFilter, BackupInfo } from '@redjay/threads-storage';
|
|
3
|
+
/**
|
|
4
|
+
* JSON file-based implementation of IFileThreadStore.
|
|
5
|
+
*
|
|
6
|
+
* Reads/writes to ~/.threads/threads.json with automatic backup on save.
|
|
7
|
+
* Uses callback pattern - all operations notify the registered IStorageClient.
|
|
8
|
+
*/
|
|
9
|
+
export declare class JsonFileStore implements IFileThreadStore {
|
|
10
|
+
private readonly dataDir;
|
|
11
|
+
private readonly dataFile;
|
|
12
|
+
private readonly backupFile;
|
|
13
|
+
private client;
|
|
14
|
+
constructor(dataDir?: string, dataFile?: string, backupFile?: string);
|
|
15
|
+
/** Set the client that receives operation callbacks. */
|
|
16
|
+
setClient(client: IStorageClient): void;
|
|
17
|
+
private ensureDataFile;
|
|
18
|
+
private migrateData;
|
|
19
|
+
private createBackup;
|
|
20
|
+
private loadData;
|
|
21
|
+
private saveData;
|
|
22
|
+
/** Get all threads. Calls client.onThreadsListed(). */
|
|
23
|
+
getAllThreads(): void;
|
|
24
|
+
/** Get a thread by its ID. Calls client.onThreadFound(). */
|
|
25
|
+
getThreadById(id: string): void;
|
|
26
|
+
/** Get a thread by its name (case-insensitive). Calls client.onThreadFound(). */
|
|
27
|
+
getThreadByName(name: string): void;
|
|
28
|
+
/** Find threads matching filter criteria. Calls client.onThreadsListed(). */
|
|
29
|
+
findThreads(filter: ThreadFilter): void;
|
|
30
|
+
/** Add a new thread. Calls client.onThreadCreated(). */
|
|
31
|
+
addThread(thread: Thread): void;
|
|
32
|
+
/** Update an existing thread. Calls client.onThreadUpdated() or onError(). */
|
|
33
|
+
updateThread(id: string, updates: Partial<Thread>): void;
|
|
34
|
+
/** Delete a thread by ID. Calls client.onThreadDeleted() or onError(). */
|
|
35
|
+
deleteThread(id: string): void;
|
|
36
|
+
/** Get all containers. Calls client.onContainersListed(). */
|
|
37
|
+
getAllContainers(): void;
|
|
38
|
+
/** Get a container by its ID. Calls client.onContainerFound(). */
|
|
39
|
+
getContainerById(id: string): void;
|
|
40
|
+
/** Get a container by its name (case-insensitive). Calls client.onContainerFound(). */
|
|
41
|
+
getContainerByName(name: string): void;
|
|
42
|
+
/** Find containers matching filter criteria. Calls client.onContainersListed(). */
|
|
43
|
+
findContainers(filter: ContainerFilter): void;
|
|
44
|
+
/** Add a new container. Calls client.onContainerCreated(). */
|
|
45
|
+
addContainer(container: Container): void;
|
|
46
|
+
/** Update an existing container. Calls client.onContainerUpdated() or onError(). */
|
|
47
|
+
updateContainer(id: string, updates: Partial<Container>): void;
|
|
48
|
+
/** Delete a container by ID. Calls client.onContainerDeleted() or onError(). */
|
|
49
|
+
deleteContainer(id: string): void;
|
|
50
|
+
/** Get all groups. Calls client.onGroupsListed(). */
|
|
51
|
+
getAllGroups(): void;
|
|
52
|
+
/** Get a group by its ID. Calls client.onGroupFound(). */
|
|
53
|
+
getGroupById(id: string): void;
|
|
54
|
+
/** Get a group by its name (case-insensitive). Calls client.onGroupFound(). */
|
|
55
|
+
getGroupByName(name: string): void;
|
|
56
|
+
/** Add a new group. Calls client.onGroupCreated(). */
|
|
57
|
+
addGroup(group: Group): void;
|
|
58
|
+
/** Update an existing group. Calls client.onGroupUpdated() or onError(). */
|
|
59
|
+
updateGroup(id: string, updates: Partial<Group>): void;
|
|
60
|
+
/** Delete a group by ID. Calls client.onGroupDeleted() or onError(). */
|
|
61
|
+
deleteGroup(id: string): void;
|
|
62
|
+
/** Get any entity (thread or container) by ID. Calls client.onEntityFound(). */
|
|
63
|
+
getEntityById(id: string): void;
|
|
64
|
+
/** Get any entity by name (case-insensitive). Calls client.onEntityFound(). */
|
|
65
|
+
getEntityByName(name: string): void;
|
|
66
|
+
/** Get all entities (threads and containers). Calls client.onEntitiesListed(). */
|
|
67
|
+
getAllEntities(): void;
|
|
68
|
+
/** Check if an entity is a container. */
|
|
69
|
+
isContainer(entity: Entity): entity is Container;
|
|
70
|
+
/** Check if an entity is a thread. */
|
|
71
|
+
isThread(entity: Entity): entity is Thread;
|
|
72
|
+
/** Get info about the backup file. */
|
|
73
|
+
getBackupInfo(): BackupInfo;
|
|
74
|
+
/** Load data from the backup file. */
|
|
75
|
+
loadBackupData(): ThreadsData | undefined;
|
|
76
|
+
/** Restore from backup (swap current and backup). Returns true if successful. */
|
|
77
|
+
restoreFromBackup(): boolean;
|
|
78
|
+
/** Get the path to the data file. */
|
|
79
|
+
getDataFilePath(): string;
|
|
80
|
+
/** Get the path to the backup file. */
|
|
81
|
+
getBackupFilePath(): string;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=JsonFileStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonFileStore.d.ts","sourceRoot":"","sources":["../src/JsonFileStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.JsonFileStore = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const DEFAULT_DATA_DIR = path.join(os.homedir(), '.threads');
|
|
41
|
+
const DEFAULT_DATA_FILE = path.join(DEFAULT_DATA_DIR, 'threads.json');
|
|
42
|
+
const DEFAULT_BACKUP_FILE = path.join(DEFAULT_DATA_DIR, 'threads.backup.json');
|
|
43
|
+
/**
|
|
44
|
+
* JSON file-based implementation of IFileThreadStore.
|
|
45
|
+
*
|
|
46
|
+
* Reads/writes to ~/.threads/threads.json with automatic backup on save.
|
|
47
|
+
* Uses callback pattern - all operations notify the registered IStorageClient.
|
|
48
|
+
*/
|
|
49
|
+
class JsonFileStore {
|
|
50
|
+
dataDir;
|
|
51
|
+
dataFile;
|
|
52
|
+
backupFile;
|
|
53
|
+
client = null;
|
|
54
|
+
constructor(dataDir = DEFAULT_DATA_DIR, dataFile = DEFAULT_DATA_FILE, backupFile = DEFAULT_BACKUP_FILE) {
|
|
55
|
+
this.dataDir = dataDir;
|
|
56
|
+
this.dataFile = dataFile;
|
|
57
|
+
this.backupFile = backupFile;
|
|
58
|
+
}
|
|
59
|
+
/** Set the client that receives operation callbacks. */
|
|
60
|
+
setClient(client) {
|
|
61
|
+
this.client = client;
|
|
62
|
+
}
|
|
63
|
+
// === Internal Helpers ===
|
|
64
|
+
ensureDataFile() {
|
|
65
|
+
if (!fs.existsSync(this.dataDir)) {
|
|
66
|
+
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
if (!fs.existsSync(this.dataFile)) {
|
|
69
|
+
const initialData = {
|
|
70
|
+
threads: [],
|
|
71
|
+
containers: [],
|
|
72
|
+
groups: [],
|
|
73
|
+
version: '1.0.0',
|
|
74
|
+
};
|
|
75
|
+
fs.writeFileSync(this.dataFile, JSON.stringify(initialData, null, 2));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
migrateData(data) {
|
|
79
|
+
if (!data.containers) {
|
|
80
|
+
data.containers = [];
|
|
81
|
+
}
|
|
82
|
+
// Ensure threads have reminders array
|
|
83
|
+
for (const thread of data.threads) {
|
|
84
|
+
if (!thread.reminders) {
|
|
85
|
+
thread.reminders = [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Migrate updatedAt → modified
|
|
89
|
+
for (const thread of data.threads) {
|
|
90
|
+
if ('updatedAt' in thread && !('modified' in thread)) {
|
|
91
|
+
thread.modified = thread.updatedAt;
|
|
92
|
+
delete thread.updatedAt;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (const container of data.containers) {
|
|
96
|
+
if ('updatedAt' in container && !('modified' in container)) {
|
|
97
|
+
container.modified = container.updatedAt;
|
|
98
|
+
delete container.updatedAt;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const group of data.groups) {
|
|
102
|
+
if ('updatedAt' in group && !('modified' in group)) {
|
|
103
|
+
group.modified = group.updatedAt;
|
|
104
|
+
delete group.updatedAt;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return data;
|
|
108
|
+
}
|
|
109
|
+
createBackup() {
|
|
110
|
+
if (fs.existsSync(this.dataFile)) {
|
|
111
|
+
fs.copyFileSync(this.dataFile, this.backupFile);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
loadData() {
|
|
115
|
+
this.ensureDataFile();
|
|
116
|
+
try {
|
|
117
|
+
const raw = fs.readFileSync(this.dataFile, 'utf-8');
|
|
118
|
+
const data = JSON.parse(raw);
|
|
119
|
+
return this.migrateData(data);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
// Try to recover from backup
|
|
123
|
+
if (fs.existsSync(this.backupFile)) {
|
|
124
|
+
try {
|
|
125
|
+
const backupRaw = fs.readFileSync(this.backupFile, 'utf-8');
|
|
126
|
+
const backupData = JSON.parse(backupRaw);
|
|
127
|
+
const migratedData = this.migrateData(backupData);
|
|
128
|
+
fs.writeFileSync(this.dataFile, JSON.stringify(migratedData, null, 2));
|
|
129
|
+
return migratedData;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Backup recovery failed
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Last resort: return empty state
|
|
136
|
+
const emptyData = { threads: [], containers: [], groups: [], version: '1.0.0' };
|
|
137
|
+
try {
|
|
138
|
+
fs.writeFileSync(this.dataFile, JSON.stringify(emptyData, null, 2));
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Write failed - continue with empty data
|
|
142
|
+
}
|
|
143
|
+
return emptyData;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
saveData(data) {
|
|
147
|
+
this.ensureDataFile();
|
|
148
|
+
this.createBackup();
|
|
149
|
+
fs.writeFileSync(this.dataFile, JSON.stringify(data, null, 2));
|
|
150
|
+
}
|
|
151
|
+
// === Thread Operations ===
|
|
152
|
+
/** Get all threads. Calls client.onThreadsListed(). */
|
|
153
|
+
getAllThreads() {
|
|
154
|
+
try {
|
|
155
|
+
const threads = this.loadData().threads;
|
|
156
|
+
this.client?.onThreadsListed(threads);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.client?.onError('getAllThreads', error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Get a thread by its ID. Calls client.onThreadFound(). */
|
|
163
|
+
getThreadById(id) {
|
|
164
|
+
try {
|
|
165
|
+
const thread = this.loadData().threads.find((t) => t.id === id);
|
|
166
|
+
this.client?.onThreadFound(thread);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
this.client?.onError('getThreadById', error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** Get a thread by its name (case-insensitive). Calls client.onThreadFound(). */
|
|
173
|
+
getThreadByName(name) {
|
|
174
|
+
try {
|
|
175
|
+
const lower = name.toLowerCase();
|
|
176
|
+
const thread = this.loadData().threads.find((t) => t.name.toLowerCase() === lower);
|
|
177
|
+
this.client?.onThreadFound(thread);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
this.client?.onError('getThreadByName', error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Find threads matching filter criteria. Calls client.onThreadsListed(). */
|
|
184
|
+
findThreads(filter) {
|
|
185
|
+
try {
|
|
186
|
+
const threads = this.loadData().threads.filter((t) => {
|
|
187
|
+
if (filter.status !== undefined && t.status !== filter.status)
|
|
188
|
+
return false;
|
|
189
|
+
if (filter.temperature !== undefined && t.temperature !== filter.temperature)
|
|
190
|
+
return false;
|
|
191
|
+
if (filter.size !== undefined && t.size !== filter.size)
|
|
192
|
+
return false;
|
|
193
|
+
if (filter.importance !== undefined && t.importance !== filter.importance)
|
|
194
|
+
return false;
|
|
195
|
+
if (filter.parentId !== undefined && t.parentId !== filter.parentId)
|
|
196
|
+
return false;
|
|
197
|
+
if (filter.groupId !== undefined && t.groupId !== filter.groupId)
|
|
198
|
+
return false;
|
|
199
|
+
if (filter.tags && filter.tags.length > 0) {
|
|
200
|
+
const threadTags = t.tags || [];
|
|
201
|
+
if (!filter.tags.some((tag) => threadTags.includes(tag)))
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (filter.search) {
|
|
205
|
+
const searchLower = filter.search.toLowerCase();
|
|
206
|
+
const inName = t.name.toLowerCase().includes(searchLower);
|
|
207
|
+
const inDesc = t.description?.toLowerCase().includes(searchLower) ?? false;
|
|
208
|
+
if (!inName && !inDesc)
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
});
|
|
213
|
+
this.client?.onThreadsListed(threads);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
this.client?.onError('findThreads', error);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/** Add a new thread. Calls client.onThreadCreated(). */
|
|
220
|
+
addThread(thread) {
|
|
221
|
+
try {
|
|
222
|
+
const data = this.loadData();
|
|
223
|
+
data.threads.push(thread);
|
|
224
|
+
this.saveData(data);
|
|
225
|
+
this.client?.onThreadCreated(thread);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
this.client?.onError('addThread', error);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** Update an existing thread. Calls client.onThreadUpdated() or onError(). */
|
|
232
|
+
updateThread(id, updates) {
|
|
233
|
+
try {
|
|
234
|
+
const data = this.loadData();
|
|
235
|
+
const index = data.threads.findIndex((t) => t.id === id);
|
|
236
|
+
if (index === -1) {
|
|
237
|
+
this.client?.onError('updateThread', new Error(`Thread not found: ${id}`));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
data.threads[index] = {
|
|
241
|
+
...data.threads[index],
|
|
242
|
+
...updates,
|
|
243
|
+
modified: new Date().toISOString(),
|
|
244
|
+
};
|
|
245
|
+
this.saveData(data);
|
|
246
|
+
this.client?.onThreadUpdated(data.threads[index]);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
this.client?.onError('updateThread', error);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/** Delete a thread by ID. Calls client.onThreadDeleted() or onError(). */
|
|
253
|
+
deleteThread(id) {
|
|
254
|
+
try {
|
|
255
|
+
const data = this.loadData();
|
|
256
|
+
const index = data.threads.findIndex((t) => t.id === id);
|
|
257
|
+
if (index === -1) {
|
|
258
|
+
this.client?.onError('deleteThread', new Error(`Thread not found: ${id}`));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
data.threads.splice(index, 1);
|
|
262
|
+
this.saveData(data);
|
|
263
|
+
this.client?.onThreadDeleted(id);
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
this.client?.onError('deleteThread', error);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// === Container Operations ===
|
|
270
|
+
/** Get all containers. Calls client.onContainersListed(). */
|
|
271
|
+
getAllContainers() {
|
|
272
|
+
try {
|
|
273
|
+
const containers = this.loadData().containers;
|
|
274
|
+
this.client?.onContainersListed(containers);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
this.client?.onError('getAllContainers', error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/** Get a container by its ID. Calls client.onContainerFound(). */
|
|
281
|
+
getContainerById(id) {
|
|
282
|
+
try {
|
|
283
|
+
const container = this.loadData().containers.find((c) => c.id === id);
|
|
284
|
+
this.client?.onContainerFound(container);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
this.client?.onError('getContainerById', error);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** Get a container by its name (case-insensitive). Calls client.onContainerFound(). */
|
|
291
|
+
getContainerByName(name) {
|
|
292
|
+
try {
|
|
293
|
+
const lower = name.toLowerCase();
|
|
294
|
+
const container = this.loadData().containers.find((c) => c.name.toLowerCase() === lower);
|
|
295
|
+
this.client?.onContainerFound(container);
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
this.client?.onError('getContainerByName', error);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Find containers matching filter criteria. Calls client.onContainersListed(). */
|
|
302
|
+
findContainers(filter) {
|
|
303
|
+
try {
|
|
304
|
+
const containers = this.loadData().containers.filter((c) => {
|
|
305
|
+
if (filter.parentId !== undefined && c.parentId !== filter.parentId)
|
|
306
|
+
return false;
|
|
307
|
+
if (filter.groupId !== undefined && c.groupId !== filter.groupId)
|
|
308
|
+
return false;
|
|
309
|
+
if (filter.tags && filter.tags.length > 0) {
|
|
310
|
+
const containerTags = c.tags || [];
|
|
311
|
+
if (!filter.tags.some((tag) => containerTags.includes(tag)))
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
if (filter.search) {
|
|
315
|
+
const searchLower = filter.search.toLowerCase();
|
|
316
|
+
const inName = c.name.toLowerCase().includes(searchLower);
|
|
317
|
+
const inDesc = c.description?.toLowerCase().includes(searchLower) ?? false;
|
|
318
|
+
if (!inName && !inDesc)
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
return true;
|
|
322
|
+
});
|
|
323
|
+
this.client?.onContainersListed(containers);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
this.client?.onError('findContainers', error);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/** Add a new container. Calls client.onContainerCreated(). */
|
|
330
|
+
addContainer(container) {
|
|
331
|
+
try {
|
|
332
|
+
const data = this.loadData();
|
|
333
|
+
data.containers.push(container);
|
|
334
|
+
this.saveData(data);
|
|
335
|
+
this.client?.onContainerCreated(container);
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
this.client?.onError('addContainer', error);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/** Update an existing container. Calls client.onContainerUpdated() or onError(). */
|
|
342
|
+
updateContainer(id, updates) {
|
|
343
|
+
try {
|
|
344
|
+
const data = this.loadData();
|
|
345
|
+
const index = data.containers.findIndex((c) => c.id === id);
|
|
346
|
+
if (index === -1) {
|
|
347
|
+
this.client?.onError('updateContainer', new Error(`Container not found: ${id}`));
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
data.containers[index] = {
|
|
351
|
+
...data.containers[index],
|
|
352
|
+
...updates,
|
|
353
|
+
modified: new Date().toISOString(),
|
|
354
|
+
};
|
|
355
|
+
this.saveData(data);
|
|
356
|
+
this.client?.onContainerUpdated(data.containers[index]);
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
this.client?.onError('updateContainer', error);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/** Delete a container by ID. Calls client.onContainerDeleted() or onError(). */
|
|
363
|
+
deleteContainer(id) {
|
|
364
|
+
try {
|
|
365
|
+
const data = this.loadData();
|
|
366
|
+
const index = data.containers.findIndex((c) => c.id === id);
|
|
367
|
+
if (index === -1) {
|
|
368
|
+
this.client?.onError('deleteContainer', new Error(`Container not found: ${id}`));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
data.containers.splice(index, 1);
|
|
372
|
+
this.saveData(data);
|
|
373
|
+
this.client?.onContainerDeleted(id);
|
|
374
|
+
}
|
|
375
|
+
catch (error) {
|
|
376
|
+
this.client?.onError('deleteContainer', error);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// === Group Operations ===
|
|
380
|
+
/** Get all groups. Calls client.onGroupsListed(). */
|
|
381
|
+
getAllGroups() {
|
|
382
|
+
try {
|
|
383
|
+
const groups = this.loadData().groups;
|
|
384
|
+
this.client?.onGroupsListed(groups);
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
this.client?.onError('getAllGroups', error);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/** Get a group by its ID. Calls client.onGroupFound(). */
|
|
391
|
+
getGroupById(id) {
|
|
392
|
+
try {
|
|
393
|
+
const group = this.loadData().groups.find((g) => g.id === id);
|
|
394
|
+
this.client?.onGroupFound(group);
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
this.client?.onError('getGroupById', error);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/** Get a group by its name (case-insensitive). Calls client.onGroupFound(). */
|
|
401
|
+
getGroupByName(name) {
|
|
402
|
+
try {
|
|
403
|
+
const lower = name.toLowerCase();
|
|
404
|
+
const group = this.loadData().groups.find((g) => g.name.toLowerCase() === lower);
|
|
405
|
+
this.client?.onGroupFound(group);
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
this.client?.onError('getGroupByName', error);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/** Add a new group. Calls client.onGroupCreated(). */
|
|
412
|
+
addGroup(group) {
|
|
413
|
+
try {
|
|
414
|
+
const data = this.loadData();
|
|
415
|
+
data.groups.push(group);
|
|
416
|
+
this.saveData(data);
|
|
417
|
+
this.client?.onGroupCreated(group);
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
this.client?.onError('addGroup', error);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/** Update an existing group. Calls client.onGroupUpdated() or onError(). */
|
|
424
|
+
updateGroup(id, updates) {
|
|
425
|
+
try {
|
|
426
|
+
const data = this.loadData();
|
|
427
|
+
const index = data.groups.findIndex((g) => g.id === id);
|
|
428
|
+
if (index === -1) {
|
|
429
|
+
this.client?.onError('updateGroup', new Error(`Group not found: ${id}`));
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
data.groups[index] = {
|
|
433
|
+
...data.groups[index],
|
|
434
|
+
...updates,
|
|
435
|
+
modified: new Date().toISOString(),
|
|
436
|
+
};
|
|
437
|
+
this.saveData(data);
|
|
438
|
+
this.client?.onGroupUpdated(data.groups[index]);
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
this.client?.onError('updateGroup', error);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/** Delete a group by ID. Calls client.onGroupDeleted() or onError(). */
|
|
445
|
+
deleteGroup(id) {
|
|
446
|
+
try {
|
|
447
|
+
const data = this.loadData();
|
|
448
|
+
const index = data.groups.findIndex((g) => g.id === id);
|
|
449
|
+
if (index === -1) {
|
|
450
|
+
this.client?.onError('deleteGroup', new Error(`Group not found: ${id}`));
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
data.groups.splice(index, 1);
|
|
454
|
+
this.saveData(data);
|
|
455
|
+
this.client?.onGroupDeleted(id);
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
this.client?.onError('deleteGroup', error);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
// === Entity Operations ===
|
|
462
|
+
/** Get any entity (thread or container) by ID. Calls client.onEntityFound(). */
|
|
463
|
+
getEntityById(id) {
|
|
464
|
+
try {
|
|
465
|
+
const data = this.loadData();
|
|
466
|
+
const thread = data.threads.find((t) => t.id === id);
|
|
467
|
+
if (thread) {
|
|
468
|
+
this.client?.onEntityFound(thread);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const container = data.containers.find((c) => c.id === id);
|
|
472
|
+
this.client?.onEntityFound(container);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
this.client?.onError('getEntityById', error);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/** Get any entity by name (case-insensitive). Calls client.onEntityFound(). */
|
|
479
|
+
getEntityByName(name) {
|
|
480
|
+
try {
|
|
481
|
+
const lower = name.toLowerCase();
|
|
482
|
+
const data = this.loadData();
|
|
483
|
+
const thread = data.threads.find((t) => t.name.toLowerCase() === lower);
|
|
484
|
+
if (thread) {
|
|
485
|
+
this.client?.onEntityFound(thread);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const container = data.containers.find((c) => c.name.toLowerCase() === lower);
|
|
489
|
+
this.client?.onEntityFound(container);
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
this.client?.onError('getEntityByName', error);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
/** Get all entities (threads and containers). Calls client.onEntitiesListed(). */
|
|
496
|
+
getAllEntities() {
|
|
497
|
+
try {
|
|
498
|
+
const data = this.loadData();
|
|
499
|
+
const entities = [...data.threads, ...data.containers];
|
|
500
|
+
this.client?.onEntitiesListed(entities);
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
this.client?.onError('getAllEntities', error);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/** Check if an entity is a container. */
|
|
507
|
+
isContainer(entity) {
|
|
508
|
+
return entity.type === 'container';
|
|
509
|
+
}
|
|
510
|
+
/** Check if an entity is a thread. */
|
|
511
|
+
isThread(entity) {
|
|
512
|
+
return entity.type !== 'container';
|
|
513
|
+
}
|
|
514
|
+
// === Backup Operations (IFileThreadStore) ===
|
|
515
|
+
/** Get info about the backup file. */
|
|
516
|
+
getBackupInfo() {
|
|
517
|
+
if (!fs.existsSync(this.backupFile)) {
|
|
518
|
+
return { exists: false };
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
const stats = fs.statSync(this.backupFile);
|
|
522
|
+
const raw = fs.readFileSync(this.backupFile, 'utf-8');
|
|
523
|
+
const data = this.migrateData(JSON.parse(raw));
|
|
524
|
+
return {
|
|
525
|
+
exists: true,
|
|
526
|
+
timestamp: stats.mtime,
|
|
527
|
+
threadCount: data.threads.length,
|
|
528
|
+
containerCount: data.containers.length,
|
|
529
|
+
groupCount: data.groups.length,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
return { exists: false };
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
/** Load data from the backup file. */
|
|
537
|
+
loadBackupData() {
|
|
538
|
+
if (!fs.existsSync(this.backupFile)) {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
try {
|
|
542
|
+
const raw = fs.readFileSync(this.backupFile, 'utf-8');
|
|
543
|
+
return this.migrateData(JSON.parse(raw));
|
|
544
|
+
}
|
|
545
|
+
catch {
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
/** Restore from backup (swap current and backup). Returns true if successful. */
|
|
550
|
+
restoreFromBackup() {
|
|
551
|
+
if (!fs.existsSync(this.backupFile)) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
this.ensureDataFile();
|
|
555
|
+
const currentData = fs.readFileSync(this.dataFile, 'utf-8');
|
|
556
|
+
const backupData = fs.readFileSync(this.backupFile, 'utf-8');
|
|
557
|
+
// Validate backup JSON before swapping
|
|
558
|
+
try {
|
|
559
|
+
JSON.parse(backupData);
|
|
560
|
+
}
|
|
561
|
+
catch {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
// Swap: backup becomes current, current becomes backup
|
|
565
|
+
fs.writeFileSync(this.dataFile, backupData);
|
|
566
|
+
fs.writeFileSync(this.backupFile, currentData);
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
/** Get the path to the data file. */
|
|
570
|
+
getDataFilePath() {
|
|
571
|
+
return this.dataFile;
|
|
572
|
+
}
|
|
573
|
+
/** Get the path to the backup file. */
|
|
574
|
+
getBackupFilePath() {
|
|
575
|
+
return this.backupFile;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
exports.JsonFileStore = JsonFileStore;
|
|
579
|
+
//# sourceMappingURL=JsonFileStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonFileStore.js","sourceRoot":"","sources":["../src/JsonFileStore.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON file-based storage implementation for Threads platform.
|
|
3
|
+
*
|
|
4
|
+
* Implements IFileThreadStore with callback pattern - all operations
|
|
5
|
+
* notify the registered IStorageClient upon completion.
|
|
6
|
+
*/
|
|
7
|
+
export { JsonFileStore } from './JsonFileStore';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* JSON file-based storage implementation for Threads platform.
|
|
4
|
+
*
|
|
5
|
+
* Implements IFileThreadStore with callback pattern - all operations
|
|
6
|
+
* notify the registered IStorageClient upon completion.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.JsonFileStore = void 0;
|
|
10
|
+
var JsonFileStore_1 = require("./JsonFileStore");
|
|
11
|
+
Object.defineProperty(exports, "JsonFileStore", { enumerable: true, get: function () { return JsonFileStore_1.JsonFileStore; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@redjay/threads-json-storage",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "JSON file storage adapter for Threads platform",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -b",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "jest --passWithNoTests"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"threads",
|
|
26
|
+
"storage",
|
|
27
|
+
"json",
|
|
28
|
+
"file"
|
|
29
|
+
],
|
|
30
|
+
"author": "Joshua Ramirez",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.0.0"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/JoshuaRamirez/threads-cli.git",
|
|
38
|
+
"directory": "packages/json-storage"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/JoshuaRamirez/threads-cli/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/JoshuaRamirez/threads-cli/tree/master/packages/json-storage#readme",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@redjay/threads-core": "workspace:*",
|
|
50
|
+
"@redjay/threads-storage": "workspace:*"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.0.0",
|
|
54
|
+
"@types/jest": "^30.0.0",
|
|
55
|
+
"jest": "^30.2.0",
|
|
56
|
+
"ts-jest": "^29.4.6",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
}
|
|
59
|
+
}
|