@concord-consortium/object-storage 1.0.0-pre.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/README.md +70 -0
- package/dist/demo-object-storage.d.ts +61 -0
- package/dist/demo-object-storage.js +154 -0
- package/dist/firebase-object-storage.d.ts +52 -0
- package/dist/firebase-object-storage.js +105 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +12 -0
- package/dist/object-storage-context.d.ts +17 -0
- package/dist/object-storage-context.js +59 -0
- package/dist/object-storage.d.ts +5 -0
- package/dist/object-storage.js +23 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.js +2 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @concord-consortium/object-storage
|
|
2
|
+
|
|
3
|
+
A TypeScript library for object storage.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @concord-consortium/object-storage
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createObjectStorage, ObjectStorageConfig } from '@concord-consortium/object-storage';
|
|
17
|
+
|
|
18
|
+
const config: ObjectStorageConfig = { type: "demo", version: 1 };
|
|
19
|
+
const storage = createObjectStorage(config);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### React Context Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { ObjectStorageProvider, useObjectStorage } from '@concord-consortium/object-storage';
|
|
26
|
+
|
|
27
|
+
function App() {
|
|
28
|
+
const config = { type: "demo", version: 1 } as const;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<ObjectStorageProvider config={config}>
|
|
32
|
+
<YourComponent />
|
|
33
|
+
</ObjectStorageProvider>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function YourComponent() {
|
|
38
|
+
const storage = useObjectStorage();
|
|
39
|
+
|
|
40
|
+
// Use storage methods
|
|
41
|
+
const handleAdd = async () => {
|
|
42
|
+
const id = await storage.add({ metadata: {}, data: {} });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return <div>Your component</div>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Development
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Install dependencies
|
|
53
|
+
npm install
|
|
54
|
+
|
|
55
|
+
# Build the library
|
|
56
|
+
npm run build
|
|
57
|
+
|
|
58
|
+
# Run tests
|
|
59
|
+
npm test
|
|
60
|
+
|
|
61
|
+
# Run tests in watch mode
|
|
62
|
+
npm run test:watch
|
|
63
|
+
|
|
64
|
+
# Run tests with coverage
|
|
65
|
+
npm run test:coverage
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { DemoObjectStorageConfig, IObjectStorage, ObjectMetadata, ObjectData, StoredObject, ObjectWithId, MonitorCallback, DemonitorFunction } from './types';
|
|
2
|
+
export declare class DemoObjectStorage implements IObjectStorage {
|
|
3
|
+
private config;
|
|
4
|
+
private objects;
|
|
5
|
+
private monitors;
|
|
6
|
+
constructor(config: DemoObjectStorageConfig);
|
|
7
|
+
/**
|
|
8
|
+
* Lists metadata documents for objects owned by the current user
|
|
9
|
+
*/
|
|
10
|
+
listMine(): Promise<ObjectWithId[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Lists metadata documents for objects linked to the current user
|
|
13
|
+
*/
|
|
14
|
+
listLinked(): Promise<ObjectWithId[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Lists metadata documents for objects associated with specific question IDs
|
|
17
|
+
*/
|
|
18
|
+
list(questionIds: string[]): Promise<ObjectWithId[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Monitors metadata documents for objects owned by the current user
|
|
21
|
+
* Invokes callback at start and on any change
|
|
22
|
+
* Returns a function to stop monitoring
|
|
23
|
+
*/
|
|
24
|
+
monitorMine(callback: MonitorCallback): DemonitorFunction;
|
|
25
|
+
/**
|
|
26
|
+
* Monitors metadata documents for objects linked to the current user
|
|
27
|
+
* Invokes callback at start and on any change
|
|
28
|
+
* Returns a function to stop monitoring
|
|
29
|
+
*/
|
|
30
|
+
monitorLinked(callback: MonitorCallback): DemonitorFunction;
|
|
31
|
+
/**
|
|
32
|
+
* Monitors metadata documents for objects associated with specific question IDs
|
|
33
|
+
* Invokes callback at start and on any change
|
|
34
|
+
* Returns a function to stop monitoring
|
|
35
|
+
*/
|
|
36
|
+
monitor(questionIds: string[], callback: MonitorCallback): DemonitorFunction;
|
|
37
|
+
/**
|
|
38
|
+
* Adds both metadata and data documents for a new object
|
|
39
|
+
* Returns the generated object ID (nanoid)
|
|
40
|
+
*/
|
|
41
|
+
add(object: StoredObject): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Reads both metadata and data documents for an object
|
|
44
|
+
* Returns undefined if the object is not found
|
|
45
|
+
*/
|
|
46
|
+
read(objectId: string): Promise<StoredObject | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Reads only the metadata document for an object
|
|
49
|
+
* Returns undefined if the object is not found
|
|
50
|
+
*/
|
|
51
|
+
readMetadata(objectId: string): Promise<ObjectMetadata | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Reads only the data document for an object
|
|
54
|
+
* Returns undefined if the object is not found
|
|
55
|
+
*/
|
|
56
|
+
readData(objectId: string): Promise<ObjectData | undefined>;
|
|
57
|
+
/**
|
|
58
|
+
* Notifies all active monitors of changes
|
|
59
|
+
*/
|
|
60
|
+
private notifyMonitors;
|
|
61
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DemoObjectStorage = void 0;
|
|
4
|
+
const nanoid_1 = require("nanoid");
|
|
5
|
+
class DemoObjectStorage {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
if (config.version !== 1) {
|
|
8
|
+
throw new Error(`Unsupported config version: ${config.version}. Expected version 1.`);
|
|
9
|
+
}
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.objects = new Map();
|
|
12
|
+
this.monitors = new Map();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Lists metadata documents for objects owned by the current user
|
|
16
|
+
*/
|
|
17
|
+
async listMine() {
|
|
18
|
+
return Array.from(this.objects.values());
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lists metadata documents for objects linked to the current user
|
|
22
|
+
*/
|
|
23
|
+
async listLinked() {
|
|
24
|
+
// not applicable in demo storage
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Lists metadata documents for objects associated with specific question IDs
|
|
29
|
+
*/
|
|
30
|
+
async list(questionIds) {
|
|
31
|
+
// In demo mode, just return all objects
|
|
32
|
+
return Array.from(this.objects.values());
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Monitors metadata documents for objects owned by the current user
|
|
36
|
+
* Invokes callback at start and on any change
|
|
37
|
+
* Returns a function to stop monitoring
|
|
38
|
+
*/
|
|
39
|
+
monitorMine(callback) {
|
|
40
|
+
const key = 'mine';
|
|
41
|
+
if (!this.monitors.has(key)) {
|
|
42
|
+
this.monitors.set(key, []);
|
|
43
|
+
}
|
|
44
|
+
this.monitors.get(key).push(callback);
|
|
45
|
+
// Invoke callback immediately with current state
|
|
46
|
+
callback(Array.from(this.objects.values()));
|
|
47
|
+
return () => {
|
|
48
|
+
const callbacks = this.monitors.get(key);
|
|
49
|
+
if (callbacks) {
|
|
50
|
+
const index = callbacks.indexOf(callback);
|
|
51
|
+
if (index > -1) {
|
|
52
|
+
callbacks.splice(index, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Monitors metadata documents for objects linked to the current user
|
|
59
|
+
* Invokes callback at start and on any change
|
|
60
|
+
* Returns a function to stop monitoring
|
|
61
|
+
*/
|
|
62
|
+
monitorLinked(callback) {
|
|
63
|
+
// not applicable in demo storage
|
|
64
|
+
callback([]);
|
|
65
|
+
return () => {
|
|
66
|
+
// no-op
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Monitors metadata documents for objects associated with specific question IDs
|
|
71
|
+
* Invokes callback at start and on any change
|
|
72
|
+
* Returns a function to stop monitoring
|
|
73
|
+
*/
|
|
74
|
+
monitor(questionIds, callback) {
|
|
75
|
+
const key = `monitor-${questionIds.join(',')}`;
|
|
76
|
+
if (!this.monitors.has(key)) {
|
|
77
|
+
this.monitors.set(key, []);
|
|
78
|
+
}
|
|
79
|
+
this.monitors.get(key).push(callback);
|
|
80
|
+
// Invoke callback immediately with current state
|
|
81
|
+
callback(Array.from(this.objects.values()));
|
|
82
|
+
return () => {
|
|
83
|
+
const callbacks = this.monitors.get(key);
|
|
84
|
+
if (callbacks) {
|
|
85
|
+
const index = callbacks.indexOf(callback);
|
|
86
|
+
if (index > -1) {
|
|
87
|
+
callbacks.splice(index, 1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Adds both metadata and data documents for a new object
|
|
94
|
+
* Returns the generated object ID (nanoid)
|
|
95
|
+
*/
|
|
96
|
+
async add(object) {
|
|
97
|
+
const id = (0, nanoid_1.nanoid)();
|
|
98
|
+
const objectWithId = {
|
|
99
|
+
id,
|
|
100
|
+
metadata: object.metadata,
|
|
101
|
+
data: object.data
|
|
102
|
+
};
|
|
103
|
+
this.objects.set(id, objectWithId);
|
|
104
|
+
// Notify all monitors
|
|
105
|
+
this.notifyMonitors();
|
|
106
|
+
return id;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Reads both metadata and data documents for an object
|
|
110
|
+
* Returns undefined if the object is not found
|
|
111
|
+
*/
|
|
112
|
+
async read(objectId) {
|
|
113
|
+
const obj = this.objects.get(objectId);
|
|
114
|
+
if (!obj) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
metadata: obj.metadata,
|
|
119
|
+
data: obj.data
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Reads only the metadata document for an object
|
|
124
|
+
* Returns undefined if the object is not found
|
|
125
|
+
*/
|
|
126
|
+
async readMetadata(objectId) {
|
|
127
|
+
const obj = this.objects.get(objectId);
|
|
128
|
+
if (!obj) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
return obj.metadata;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Reads only the data document for an object
|
|
135
|
+
* Returns undefined if the object is not found
|
|
136
|
+
*/
|
|
137
|
+
async readData(objectId) {
|
|
138
|
+
const obj = this.objects.get(objectId);
|
|
139
|
+
if (!obj) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
return obj.data;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Notifies all active monitors of changes
|
|
146
|
+
*/
|
|
147
|
+
notifyMonitors() {
|
|
148
|
+
const allObjects = Array.from(this.objects.values());
|
|
149
|
+
this.monitors.forEach(callbacks => {
|
|
150
|
+
callbacks.forEach(callback => callback(allObjects));
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.DemoObjectStorage = DemoObjectStorage;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FirebaseObjectStorageConfig, IObjectStorage, ObjectMetadata, ObjectData, StoredObject, ObjectWithId, MonitorCallback, DemonitorFunction } from './types';
|
|
2
|
+
export declare class FirebaseObjectStorage implements IObjectStorage {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: FirebaseObjectStorageConfig);
|
|
5
|
+
/**
|
|
6
|
+
* Lists metadata documents for objects owned by the current user
|
|
7
|
+
*/
|
|
8
|
+
listMine(): Promise<ObjectWithId[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Lists metadata documents for objects linked to the current user
|
|
11
|
+
*/
|
|
12
|
+
listLinked(): Promise<ObjectWithId[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Lists metadata documents for objects associated with specific question IDs
|
|
15
|
+
*/
|
|
16
|
+
list(questionIds: string[]): Promise<ObjectWithId[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Monitors metadata documents for objects owned by the current user
|
|
19
|
+
* Invokes callback at start and on any change
|
|
20
|
+
* Returns a function to stop monitoring
|
|
21
|
+
*/
|
|
22
|
+
monitorMine(callback: MonitorCallback): DemonitorFunction;
|
|
23
|
+
/**
|
|
24
|
+
* Monitors metadata documents for objects linked to the current user
|
|
25
|
+
* Invokes callback at start and on any change
|
|
26
|
+
* Returns a function to stop monitoring
|
|
27
|
+
*/
|
|
28
|
+
monitorLinked(callback: MonitorCallback): DemonitorFunction;
|
|
29
|
+
/**
|
|
30
|
+
* Monitors metadata documents for objects associated with specific question IDs
|
|
31
|
+
* Invokes callback at start and on any change
|
|
32
|
+
* Returns a function to stop monitoring
|
|
33
|
+
*/
|
|
34
|
+
monitor(questionIds: string[], callback: MonitorCallback): DemonitorFunction;
|
|
35
|
+
/**
|
|
36
|
+
* Adds both metadata and data documents for a new object
|
|
37
|
+
* Returns the generated object ID (nanoid)
|
|
38
|
+
*/
|
|
39
|
+
add(object: StoredObject): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Reads both metadata and data documents for an object
|
|
42
|
+
*/
|
|
43
|
+
read(objectId: string): Promise<StoredObject | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Reads only the metadata document for an object
|
|
46
|
+
*/
|
|
47
|
+
readMetadata(objectId: string): Promise<ObjectMetadata | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* Reads only the data document for an object
|
|
50
|
+
*/
|
|
51
|
+
readData(objectId: string): Promise<ObjectData | undefined>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FirebaseObjectStorage = void 0;
|
|
4
|
+
class FirebaseObjectStorage {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
if (config.version !== 1) {
|
|
7
|
+
throw new Error(`Unsupported config version: ${config.version}. Expected version 1.`);
|
|
8
|
+
}
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Lists metadata documents for objects owned by the current user
|
|
13
|
+
*/
|
|
14
|
+
async listMine() {
|
|
15
|
+
// TODO: Implement Firebase query for user's own objects
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Lists metadata documents for objects linked to the current user
|
|
20
|
+
*/
|
|
21
|
+
async listLinked() {
|
|
22
|
+
// TODO: Implement Firebase query for linked objects
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Lists metadata documents for objects associated with specific question IDs
|
|
27
|
+
*/
|
|
28
|
+
async list(questionIds) {
|
|
29
|
+
// TODO: Implement Firebase query for objects by question IDs
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Monitors metadata documents for objects owned by the current user
|
|
34
|
+
* Invokes callback at start and on any change
|
|
35
|
+
* Returns a function to stop monitoring
|
|
36
|
+
*/
|
|
37
|
+
monitorMine(callback) {
|
|
38
|
+
// TODO: Implement Firebase realtime listener for user's own objects
|
|
39
|
+
callback([]);
|
|
40
|
+
return () => {
|
|
41
|
+
// TODO: Implement cleanup
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Monitors metadata documents for objects linked to the current user
|
|
46
|
+
* Invokes callback at start and on any change
|
|
47
|
+
* Returns a function to stop monitoring
|
|
48
|
+
*/
|
|
49
|
+
monitorLinked(callback) {
|
|
50
|
+
// TODO: Implement Firebase realtime listener for linked objects
|
|
51
|
+
callback([]);
|
|
52
|
+
return () => {
|
|
53
|
+
// TODO: Implement cleanup
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Monitors metadata documents for objects associated with specific question IDs
|
|
58
|
+
* Invokes callback at start and on any change
|
|
59
|
+
* Returns a function to stop monitoring
|
|
60
|
+
*/
|
|
61
|
+
monitor(questionIds, callback) {
|
|
62
|
+
// TODO: Implement Firebase realtime listener for objects by question IDs
|
|
63
|
+
callback([]);
|
|
64
|
+
return () => {
|
|
65
|
+
// TODO: Implement cleanup
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Adds both metadata and data documents for a new object
|
|
70
|
+
* Returns the generated object ID (nanoid)
|
|
71
|
+
*/
|
|
72
|
+
async add(object) {
|
|
73
|
+
// TODO: Generate nanoid
|
|
74
|
+
// TODO: Add metadata document to Firebase
|
|
75
|
+
// TODO: Add data document to Firebase
|
|
76
|
+
const newObjectId = 'placeholder-id';
|
|
77
|
+
return newObjectId;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reads both metadata and data documents for an object
|
|
81
|
+
*/
|
|
82
|
+
async read(objectId) {
|
|
83
|
+
// TODO: Read metadata document from Firebase
|
|
84
|
+
// TODO: Read data document from Firebase
|
|
85
|
+
return {
|
|
86
|
+
metadata: {},
|
|
87
|
+
data: {}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Reads only the metadata document for an object
|
|
92
|
+
*/
|
|
93
|
+
async readMetadata(objectId) {
|
|
94
|
+
// TODO: Read metadata document from Firebase
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Reads only the data document for an object
|
|
99
|
+
*/
|
|
100
|
+
async readData(objectId) {
|
|
101
|
+
// TODO: Read data document from Firebase
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.FirebaseObjectStorage = FirebaseObjectStorage;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DemoObjectStorage } from './demo-object-storage';
|
|
2
|
+
export { FirebaseObjectStorage } from './firebase-object-storage';
|
|
3
|
+
export { createObjectStorage } from './object-storage';
|
|
4
|
+
export { ObjectStorageProvider, useObjectStorage } from './object-storage-context';
|
|
5
|
+
export { IObjectStorage, ObjectStorageConfig, DemoObjectStorageConfig, FirebaseObjectStorageConfig, ObjectMetadata, ObjectData, StoredObject, ObjectWithId, MonitorCallback, DemonitorFunction } from './types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useObjectStorage = exports.ObjectStorageProvider = exports.createObjectStorage = exports.FirebaseObjectStorage = exports.DemoObjectStorage = void 0;
|
|
4
|
+
var demo_object_storage_1 = require("./demo-object-storage");
|
|
5
|
+
Object.defineProperty(exports, "DemoObjectStorage", { enumerable: true, get: function () { return demo_object_storage_1.DemoObjectStorage; } });
|
|
6
|
+
var firebase_object_storage_1 = require("./firebase-object-storage");
|
|
7
|
+
Object.defineProperty(exports, "FirebaseObjectStorage", { enumerable: true, get: function () { return firebase_object_storage_1.FirebaseObjectStorage; } });
|
|
8
|
+
var object_storage_1 = require("./object-storage");
|
|
9
|
+
Object.defineProperty(exports, "createObjectStorage", { enumerable: true, get: function () { return object_storage_1.createObjectStorage; } });
|
|
10
|
+
var object_storage_context_1 = require("./object-storage-context");
|
|
11
|
+
Object.defineProperty(exports, "ObjectStorageProvider", { enumerable: true, get: function () { return object_storage_context_1.ObjectStorageProvider; } });
|
|
12
|
+
Object.defineProperty(exports, "useObjectStorage", { enumerable: true, get: function () { return object_storage_context_1.useObjectStorage; } });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import { ObjectStorageConfig, IObjectStorage } from './types';
|
|
3
|
+
interface ObjectStorageProviderProps {
|
|
4
|
+
config?: ObjectStorageConfig;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Provider component that creates and provides an ObjectStorage instance
|
|
9
|
+
* based on the supplied configuration
|
|
10
|
+
*/
|
|
11
|
+
export declare function ObjectStorageProvider({ config, children }: ObjectStorageProviderProps): React.JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* Hook to access the ObjectStorage instance from context
|
|
14
|
+
* Must be used within an ObjectStorageProvider
|
|
15
|
+
*/
|
|
16
|
+
export declare function useObjectStorage(): IObjectStorage;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
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.ObjectStorageProvider = ObjectStorageProvider;
|
|
37
|
+
exports.useObjectStorage = useObjectStorage;
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const object_storage_1 = require("./object-storage");
|
|
40
|
+
const ObjectStorageContext = (0, react_1.createContext)(null);
|
|
41
|
+
/**
|
|
42
|
+
* Provider component that creates and provides an ObjectStorage instance
|
|
43
|
+
* based on the supplied configuration
|
|
44
|
+
*/
|
|
45
|
+
function ObjectStorageProvider({ config, children }) {
|
|
46
|
+
const objectStorage = (0, react_1.useMemo)(() => (0, object_storage_1.createObjectStorage)(config), [config]);
|
|
47
|
+
return (react_1.default.createElement(ObjectStorageContext.Provider, { value: objectStorage }, children));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Hook to access the ObjectStorage instance from context
|
|
51
|
+
* Must be used within an ObjectStorageProvider
|
|
52
|
+
*/
|
|
53
|
+
function useObjectStorage() {
|
|
54
|
+
const context = (0, react_1.useContext)(ObjectStorageContext);
|
|
55
|
+
if (!context) {
|
|
56
|
+
throw new Error('useObjectStorage must be used within an ObjectStorageProvider');
|
|
57
|
+
}
|
|
58
|
+
return context;
|
|
59
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createObjectStorage = createObjectStorage;
|
|
4
|
+
const demo_object_storage_1 = require("./demo-object-storage");
|
|
5
|
+
const firebase_object_storage_1 = require("./firebase-object-storage");
|
|
6
|
+
/**
|
|
7
|
+
* Factory function to create the appropriate ObjectStorage instance based on config type
|
|
8
|
+
*/
|
|
9
|
+
function createObjectStorage(config) {
|
|
10
|
+
if (!config) {
|
|
11
|
+
throw new Error('ObjectStorageConfig is required to create an ObjectStorage instance');
|
|
12
|
+
}
|
|
13
|
+
switch (config.type) {
|
|
14
|
+
case "demo":
|
|
15
|
+
return new demo_object_storage_1.DemoObjectStorage(config);
|
|
16
|
+
case "firebase":
|
|
17
|
+
return new firebase_object_storage_1.FirebaseObjectStorage(config);
|
|
18
|
+
default:
|
|
19
|
+
// TypeScript exhaustiveness check
|
|
20
|
+
const _exhaustive = config;
|
|
21
|
+
throw new Error(`Unknown config type: ${_exhaustive.type}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface DemoObjectStorageConfig {
|
|
2
|
+
type: "demo";
|
|
3
|
+
version: 1;
|
|
4
|
+
}
|
|
5
|
+
export interface FirebaseObjectStorageConfig {
|
|
6
|
+
type: "firebase";
|
|
7
|
+
version: 1;
|
|
8
|
+
}
|
|
9
|
+
export type ObjectStorageConfig = DemoObjectStorageConfig | FirebaseObjectStorageConfig;
|
|
10
|
+
export interface IObjectStorage {
|
|
11
|
+
listMine(): Promise<ObjectWithId[]>;
|
|
12
|
+
listLinked(): Promise<ObjectWithId[]>;
|
|
13
|
+
list(questionIds: string[]): Promise<ObjectWithId[]>;
|
|
14
|
+
monitorMine(callback: MonitorCallback): DemonitorFunction;
|
|
15
|
+
monitorLinked(callback: MonitorCallback): DemonitorFunction;
|
|
16
|
+
monitor(questionIds: string[], callback: MonitorCallback): DemonitorFunction;
|
|
17
|
+
add(object: StoredObject): Promise<string>;
|
|
18
|
+
read(objectId: string): Promise<StoredObject | undefined>;
|
|
19
|
+
readMetadata(objectId: string): Promise<ObjectMetadata | undefined>;
|
|
20
|
+
readData(objectId: string): Promise<ObjectData | undefined>;
|
|
21
|
+
}
|
|
22
|
+
export interface ObjectMetadata {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
}
|
|
25
|
+
export interface ObjectData {
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
export interface StoredObject {
|
|
29
|
+
metadata: ObjectMetadata;
|
|
30
|
+
data: ObjectData;
|
|
31
|
+
}
|
|
32
|
+
export interface ObjectWithId extends StoredObject {
|
|
33
|
+
id: string;
|
|
34
|
+
}
|
|
35
|
+
export type MonitorCallback = (objects: ObjectWithId[]) => void;
|
|
36
|
+
export type DemonitorFunction = () => void;
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@concord-consortium/object-storage",
|
|
3
|
+
"version": "1.0.0-pre.0",
|
|
4
|
+
"description": "A TypeScript library for object storage",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"test:watch": "jest --watch",
|
|
11
|
+
"test:coverage": "jest --coverage",
|
|
12
|
+
"prepublishOnly": "npm run build",
|
|
13
|
+
"publish": "npm publish"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"object-storage",
|
|
17
|
+
"storage"
|
|
18
|
+
],
|
|
19
|
+
"author": "Concord Consortium",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"nanoid": "^3.3.7"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^16.8.0 || ^17.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "^29.5.0",
|
|
35
|
+
"@types/react": "^17.0.39",
|
|
36
|
+
"jest": "^29.5.0",
|
|
37
|
+
"react": "^17.0.2",
|
|
38
|
+
"ts-jest": "^29.1.0",
|
|
39
|
+
"typescript": "^5.3.0"
|
|
40
|
+
}
|
|
41
|
+
}
|