@did-space/core 0.2.173 → 0.3.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.
Files changed (41) hide show
  1. package/dist/drivers/base.d.ts +5 -5
  2. package/dist/drivers/base.js +8 -8
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +1 -0
  5. package/dist/meta/object.d.ts +5 -0
  6. package/dist/model/index.d.ts +3 -0
  7. package/dist/model/index.js +19 -0
  8. package/dist/model/object-collection.d.ts +28 -0
  9. package/dist/model/object-collection.js +7 -0
  10. package/dist/model/object.d.ts +59 -0
  11. package/dist/model/object.js +7 -0
  12. package/dist/model/tree.d.ts +94 -0
  13. package/dist/model/tree.js +18 -0
  14. package/dist/protocols/space-operator.d.ts +2 -0
  15. package/dist/protocols/space-owner-operator.d.ts +30 -4
  16. package/dist/schemas/global-space.d.ts +2 -0
  17. package/dist/schemas/global-space.js +21 -0
  18. package/dist/schemas/index.d.ts +1 -0
  19. package/dist/schemas/index.js +1 -0
  20. package/dist/schemas/object-space.d.ts +6 -0
  21. package/dist/schemas/object-space.js +39 -0
  22. package/dist/space/global-space.d.ts +43 -0
  23. package/dist/space/global-space.js +153 -0
  24. package/dist/space/index.d.ts +3 -45
  25. package/dist/space/index.js +16 -187
  26. package/dist/space/object-space.d.ts +111 -0
  27. package/dist/space/object-space.js +652 -0
  28. package/dist/space/space.d.ts +45 -0
  29. package/dist/space/space.js +190 -0
  30. package/dist/utils/common.d.ts +3 -0
  31. package/dist/utils/common.js +17 -0
  32. package/dist/utils/hash.d.ts +20 -0
  33. package/dist/utils/hash.js +60 -0
  34. package/dist/utils/index.d.ts +3 -2
  35. package/dist/utils/index.js +3 -2
  36. package/dist/utils/{string-to-stream.d.ts → stream.d.ts} +2 -0
  37. package/dist/utils/stream.js +23 -0
  38. package/package.json +11 -2
  39. package/dist/utils/stream-to-string.d.ts +0 -1
  40. package/dist/utils/stream-to-string.js +0 -10
  41. package/dist/utils/string-to-stream.js +0 -11
@@ -2,7 +2,7 @@
2
2
  import { Stream } from 'stream';
3
3
  import { SpaceConfig } from '../configuration';
4
4
  import { Data, Object } from '../meta';
5
- import { AppSpaceOptions, DeleteOptions, DriverOptions, DriverProtocol, GetHashOptions, KeyStatus, ListOptions, ListsOptions, PermissionOptions, ReadOptions, SpaceConfigProtocol, SpaceOperatorProtocol, WriteOptions } from '../protocols';
5
+ import { AppSpaceOptions, DeleteOptions, DriverOptions, DriverProtocol, ExistsAsOwnerOptions, GetHashOptions, KeyStatus, ListOptions, ListsOptions, PermissionOptions, ReadAsOwnerOptions, ReadOptions, SpaceConfigProtocol, SpaceOperatorProtocol, WriteAsOwnerOptions, WriteOptions } from '../protocols';
6
6
  export declare abstract class BaseDriver implements DriverProtocol {
7
7
  readonly options: DriverOptions;
8
8
  constructor(options: DriverOptions);
@@ -32,9 +32,9 @@ export declare abstract class BaseDriver implements DriverProtocol {
32
32
  exists(options: ReadOptions): Promise<boolean>;
33
33
  lists(options: ListsOptions): Promise<Object[]>;
34
34
  list(options: ListOptions): Promise<Object>;
35
- writeAsOwner(key: string, data: Data): Promise<void>;
36
- deleteAsOwner(key: string): Promise<void>;
37
- readAsOwner(key: string): Promise<Stream>;
38
- existsAsOwner(key: string): Promise<boolean>;
35
+ writeAsOwner(key: string, data: Data, options?: WriteAsOwnerOptions): Promise<void>;
36
+ deleteAsOwner(key: string, options?: ReadAsOwnerOptions): Promise<void>;
37
+ readAsOwner(key: string, options?: ReadAsOwnerOptions): Promise<Stream>;
38
+ existsAsOwner(key: string, options?: ExistsAsOwnerOptions): Promise<boolean>;
39
39
  getStatusAsOwner(key: string): Promise<KeyStatus>;
40
40
  }
@@ -134,17 +134,17 @@ class BaseDriver {
134
134
  list(options) {
135
135
  return this.spaceOperator.list(options);
136
136
  }
137
- writeAsOwner(key, data) {
138
- return this.spaceOperator.writeAsOwner(key, data);
137
+ writeAsOwner(key, data, options) {
138
+ return this.spaceOperator.writeAsOwner(key, data, options);
139
139
  }
140
- deleteAsOwner(key) {
141
- return this.spaceOperator.deleteAsOwner(key);
140
+ deleteAsOwner(key, options) {
141
+ return this.spaceOperator.deleteAsOwner(key, options);
142
142
  }
143
- readAsOwner(key) {
144
- return this.spaceOperator.readAsOwner(key);
143
+ readAsOwner(key, options) {
144
+ return this.spaceOperator.readAsOwner(key, options);
145
145
  }
146
- existsAsOwner(key) {
147
- return this.spaceOperator.existsAsOwner(key);
146
+ existsAsOwner(key, options) {
147
+ return this.spaceOperator.existsAsOwner(key, options);
148
148
  }
149
149
  getStatusAsOwner(key) {
150
150
  return this.spaceOperator.getStatusAsOwner(key);
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './configuration';
2
2
  export * from './constants';
3
3
  export * from './drivers';
4
4
  export * from './meta';
5
+ export * from './model';
5
6
  export * from './protocols';
6
7
  export * from './schemas';
7
8
  export * from './space';
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ __exportStar(require("./configuration"), exports);
18
18
  __exportStar(require("./constants"), exports);
19
19
  __exportStar(require("./drivers"), exports);
20
20
  __exportStar(require("./meta"), exports);
21
+ __exportStar(require("./model"), exports);
21
22
  __exportStar(require("./protocols"), exports);
22
23
  __exportStar(require("./schemas"), exports);
23
24
  __exportStar(require("./space"), exports);
@@ -13,6 +13,11 @@ export interface Object {
13
13
  size: number;
14
14
  lastModified: number;
15
15
  editable: boolean;
16
+ /**
17
+ * @description 如果是一个文件夹,则为 null
18
+ * @type {string}
19
+ * @memberof Object
20
+ */
16
21
  mimeType: string;
17
22
  [key: string]: any;
18
23
  }
@@ -0,0 +1,3 @@
1
+ export * from './tree';
2
+ export * from './object';
3
+ export * from './object-collection';
@@ -0,0 +1,19 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./tree"), exports);
18
+ __exportStar(require("./object"), exports);
19
+ __exportStar(require("./object-collection"), exports);
@@ -0,0 +1,28 @@
1
+ import { Model } from 'skypesky-sequelize';
2
+ /**
3
+ * @description 存储的是对象的信息,不保存结构,创建之初就确定了,只能增加,删除
4
+ * @export
5
+ * @interface ObjectModel
6
+ */
7
+ export interface ObjectCollectionModel {
8
+ /**
9
+ * @primaryKey
10
+ * @description 对象的唯一标识,格式是 ipfs cid v1
11
+ * @type {string}
12
+ * @column {DataTypes.CHAR(64)}
13
+ * @memberof ObjectCollectionModel
14
+ */
15
+ id: string;
16
+ /**
17
+ * @description 对象的创建时间
18
+ * @type {string}
19
+ * @column {DataTypes.DATE}
20
+ * @memberof ObjectCollectionModel
21
+ */
22
+ createdAt: string;
23
+ }
24
+ export declare class ObjectCollectionRepositoryClass extends Model<ObjectCollectionModel> implements ObjectCollectionModel {
25
+ id: string;
26
+ createdAt: string;
27
+ }
28
+ export type ObjectCollectionRepository = typeof ObjectCollectionRepositoryClass;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectCollectionRepositoryClass = void 0;
4
+ const skypesky_sequelize_1 = require("skypesky-sequelize");
5
+ class ObjectCollectionRepositoryClass extends skypesky_sequelize_1.Model {
6
+ }
7
+ exports.ObjectCollectionRepositoryClass = ObjectCollectionRepositoryClass;
@@ -0,0 +1,59 @@
1
+ import { Model } from 'skypesky-sequelize';
2
+ /**
3
+ * @description 存储的是对象的信息,不保存结构,创建之初就确定了,只能增加,删除
4
+ * @export
5
+ * @interface ObjectModel
6
+ */
7
+ export interface ObjectModel {
8
+ /**
9
+ * @primaryKey
10
+ * @description 对象的唯一标识,格式是 ipfs cid v1
11
+ * @type {string}
12
+ * @column {DataTypes.STRING(59)}
13
+ * @memberof ObjectModel
14
+ */
15
+ id: string;
16
+ /**
17
+ * @description 对象的大小
18
+ * @type {number}
19
+ * @column {DataTypes.BIGINT.UNSIGNED}
20
+ * @memberof ObjectModel
21
+ */
22
+ size: number;
23
+ /**
24
+ * @description 存储对象的元数据
25
+ * @type {ObjectModelMeta}
26
+ * @column {DataTypes.JSON}
27
+ * @memberof ObjectModel
28
+ */
29
+ meta: ObjectModelMeta;
30
+ /**
31
+ * @description 对象的创建时间
32
+ * @type {string}
33
+ * @column {DataTypes.DATE}
34
+ * @memberof ObjectModel
35
+ */
36
+ createdAt: string;
37
+ }
38
+ export interface ObjectModelMeta {
39
+ /**
40
+ *
41
+ * @description 对象的 hash,如果对象是文件夹则为 null,否则必须有值
42
+ * @type {string}
43
+ * @memberof ObjectModelMeta
44
+ */
45
+ mimeType: string;
46
+ /**
47
+ * @description 保存这个对象第一次出现的文件名
48
+ * @type {string}
49
+ * @memberof ObjectModelMeta
50
+ */
51
+ key: string;
52
+ }
53
+ export declare class ObjectRepositoryClass extends Model<ObjectModel> implements ObjectModel {
54
+ id: string;
55
+ size: number;
56
+ meta: ObjectModelMeta;
57
+ createdAt: string;
58
+ }
59
+ export type ObjectRepository = typeof ObjectRepositoryClass;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectRepositoryClass = void 0;
4
+ const skypesky_sequelize_1 = require("skypesky-sequelize");
5
+ class ObjectRepositoryClass extends skypesky_sequelize_1.Model {
6
+ }
7
+ exports.ObjectRepositoryClass = ObjectRepositoryClass;
@@ -0,0 +1,94 @@
1
+ import { Model } from 'skypesky-sequelize';
2
+ import { ObjectModel } from './object';
3
+ export interface TreeModel {
4
+ /**
5
+ * @description uuidv4
6
+ * @type {string}
7
+ * @column {DataTypes.BIGINT.UNSIGNED}
8
+ * @memberof Tree
9
+ */
10
+ id: string;
11
+ /**
12
+ * @description Space 的 DID
13
+ * @type {string}
14
+ * @column {DataTypes.STRING(40)}
15
+ * @memberof Tree
16
+ */
17
+ spaceDid: string;
18
+ /**
19
+ * @description 当且仅当,指向文件夹的时候才为空
20
+ * @type {string}
21
+ * @column {DataTypes.CHAR(64)}
22
+ * @memberof Tree
23
+ */
24
+ objectId: null | string;
25
+ /**
26
+ * @description 绑定对象的上一级目录的 id
27
+ * @example /abc/
28
+ * @type {string}
29
+ * @column {DataTypes.BIGINT.UNSIGNED}
30
+ * @memberof Tree
31
+ */
32
+ parentId: string;
33
+ /**
34
+ * @description 等价于文件夹和文件的路径,注意不包含 SpaceDid
35
+ * @example /app 或 /app/objects
36
+ * @type {string}
37
+ * @column {DataTypes.STRING(1024)}
38
+ * @memberof Tree
39
+ */
40
+ key: string;
41
+ /**
42
+ * @description folder or file
43
+ * @type {number}
44
+ * @column {DataTypes.TINYINT.UNSIGNED({ length: 1 })}
45
+ * @memberof Tree
46
+ */
47
+ type: number;
48
+ /**
49
+ *
50
+ * @description
51
+ * @default {{}}
52
+ * @type {TreeMeta}
53
+ * @column {DataTypes.JSON}
54
+ * @memberof Tree
55
+ */
56
+ meta: TreeModelMeta;
57
+ /**
58
+ * @description
59
+ * @type {string}
60
+ * @column {DataTypes.DATE}
61
+ * @memberof Tree
62
+ */
63
+ createdAt: string;
64
+ /**
65
+ * @description
66
+ * @type {string}
67
+ * @column {DataTypes.DATE}
68
+ * @memberof Tree
69
+ */
70
+ updatedAt: string;
71
+ }
72
+ export interface TreeModelMeta {
73
+ }
74
+ export type CreationTreeModel = Omit<TreeModel, 'id' | 'createdAt' | 'updatedAt' | 'meta'>;
75
+ export declare class TreeRepositoryClass extends Model<TreeModel, CreationTreeModel> implements TreeModel {
76
+ id: string;
77
+ spaceDid: string;
78
+ objectId: string;
79
+ parentId: string;
80
+ key: string;
81
+ type: number;
82
+ meta: TreeModelMeta;
83
+ createdAt: string;
84
+ updatedAt: string;
85
+ Object: ObjectModel;
86
+ static deepCreate(data: CreationTreeModel): Promise<TreeModel>;
87
+ [key: string]: any;
88
+ }
89
+ export type TreeRepository = typeof TreeRepositoryClass;
90
+ export declare enum TreeModelType {
91
+ FOLDER = 0,
92
+ FILE = 1
93
+ }
94
+ export declare const TreeModelDefaultMeta: {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeModelDefaultMeta = exports.TreeModelType = exports.TreeRepositoryClass = void 0;
4
+ const skypesky_sequelize_1 = require("skypesky-sequelize");
5
+ class TreeRepositoryClass extends skypesky_sequelize_1.Model {
6
+ // 不需要实现,只需要类型提示而已
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
+ static deepCreate(data) {
9
+ throw new Error('not implemented');
10
+ }
11
+ }
12
+ exports.TreeRepositoryClass = TreeRepositoryClass;
13
+ var TreeModelType;
14
+ (function (TreeModelType) {
15
+ TreeModelType[TreeModelType["FOLDER"] = 0] = "FOLDER";
16
+ TreeModelType[TreeModelType["FILE"] = 1] = "FILE";
17
+ })(TreeModelType = exports.TreeModelType || (exports.TreeModelType = {}));
18
+ exports.TreeModelDefaultMeta = {};
@@ -10,6 +10,7 @@ export interface WriteOptions extends AppSpaceOptions {
10
10
  key: string;
11
11
  data: Data;
12
12
  hash?: string;
13
+ size?: string;
13
14
  }
14
15
  export interface DeleteOptions extends AppSpaceOptions {
15
16
  key: string;
@@ -40,6 +41,7 @@ export interface ListsOptions {
40
41
  * @memberof ListOptions
41
42
  */
42
43
  ignoreDirectories?: boolean;
44
+ useGlobal?: false | true;
43
45
  }
44
46
  export interface SpaceOperatorProtocol extends SpaceOwnerOperatorProtocol {
45
47
  createSpace(spaceConfig: SpaceConfig): Promise<void>;
@@ -2,14 +2,40 @@
2
2
  import { Stream } from 'stream';
3
3
  import { Data } from '../meta';
4
4
  export type KeyStatus = {
5
+ /**
6
+ * @description 文件夹已存储的对象个数
7
+ * @type {number}
8
+ */
5
9
  objects: number;
10
+ /**
11
+ * @description 文件夹的最新修改时间
12
+ * @type {number}
13
+ */
6
14
  lastModified: number;
15
+ /**
16
+ * @description 文件夹的总大小
17
+ * @type {number}
18
+ */
7
19
  size: number;
8
20
  };
21
+ export type WriteAsOwnerOptions = {
22
+ hash: string;
23
+ size: number;
24
+ useGlobal?: false | true;
25
+ };
26
+ export type ReadAsOwnerOptions = {
27
+ useGlobal?: false | true;
28
+ };
29
+ export type DeleteAsOwnerOptions = {
30
+ useGlobal?: false | true;
31
+ };
32
+ export type ExistsAsOwnerOptions = {
33
+ useGlobal?: false | true;
34
+ };
9
35
  export interface SpaceOwnerOperatorProtocol {
10
- writeAsOwner(key: string, data: Data): Promise<void>;
11
- deleteAsOwner(key: string): Promise<void>;
12
- readAsOwner(key: string): Promise<Stream>;
13
- existsAsOwner(key: string): Promise<boolean>;
36
+ writeAsOwner(key: string, data: Data, options?: WriteAsOwnerOptions): Promise<void>;
37
+ deleteAsOwner(key: string, options?: DeleteAsOwnerOptions): Promise<void>;
38
+ readAsOwner(key: string, options?: ReadAsOwnerOptions): Promise<Stream>;
39
+ existsAsOwner(key: string, options?: ExistsAsOwnerOptions): Promise<boolean>;
14
40
  getStatusAsOwner(key: string): Promise<KeyStatus>;
15
41
  }
@@ -0,0 +1,2 @@
1
+ export declare const GlobalSpaceOptionsSchema: import("joi").ObjectSchema<any>;
2
+ export declare const HashSchema: import("joi").StringSchema<string>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HashSchema = exports.GlobalSpaceOptionsSchema = void 0;
4
+ const validator_1 = require("@arcblock/validator");
5
+ const utils_1 = require("../utils");
6
+ exports.GlobalSpaceOptionsSchema = validator_1.Joi.object({
7
+ driver: validator_1.Joi.any().required(),
8
+ treeRepository: validator_1.Joi.any().required(),
9
+ objectRepository: validator_1.Joi.any().required(),
10
+ objectCollectionRepository: validator_1.Joi.any().required(),
11
+ gcMaxCount: validator_1.Joi.number().integer().optional().default(100),
12
+ gcMaxConcurrency: validator_1.Joi.number().integer().optional().default(8),
13
+ });
14
+ exports.HashSchema = validator_1.Joi.string()
15
+ .custom((value, helper) => {
16
+ if (!(0, utils_1.isCidV1)(value)) {
17
+ return helper.error(`Invalid hash(${value})`);
18
+ }
19
+ return value;
20
+ })
21
+ .required();
@@ -1,2 +1,3 @@
1
1
  export * from './space-options';
2
2
  export * from './space-configuration';
3
+ export * from './object-space';
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./space-options"), exports);
18
18
  __exportStar(require("./space-configuration"), exports);
19
+ __exportStar(require("./object-space"), exports);
@@ -0,0 +1,6 @@
1
+ export declare const KeySchema: import("joi").StringSchema<string>;
2
+ export declare const WriteAsOwnerOptionsSchema: import("joi").ObjectSchema<any>;
3
+ export declare const ObjectSpaceOptionsSchema: import("joi").ObjectSchema<any>;
4
+ export declare const DeleteAsOwnerOptionsSchema: import("joi").ObjectSchema<any>;
5
+ export declare const WriteOptionsSchema: import("joi").ObjectSchema<any>;
6
+ export declare const GetHashOptionsSchema: import("joi").ObjectSchema<any>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetHashOptionsSchema = exports.WriteOptionsSchema = exports.DeleteAsOwnerOptionsSchema = exports.ObjectSpaceOptionsSchema = exports.WriteAsOwnerOptionsSchema = exports.KeySchema = void 0;
4
+ const validator_1 = require("@arcblock/validator");
5
+ exports.KeySchema = validator_1.Joi.string().regex(/^\//).required();
6
+ const WriteAsOwnerOptionsByFolderSchema = {
7
+ is: validator_1.Joi.string().regex(/\/$/),
8
+ then: validator_1.Joi.valid(null).default(null),
9
+ otherwise: validator_1.Joi.required(),
10
+ };
11
+ exports.WriteAsOwnerOptionsSchema = validator_1.Joi.object({
12
+ key: exports.KeySchema,
13
+ data: validator_1.Joi.any().when('key', WriteAsOwnerOptionsByFolderSchema),
14
+ // @FIXME: 当 key 是文件夹 或者 data 不是一个 stream 的时候,hash, size 是可选的,现在的规则尝试之后没能做到这么精细化(使用 when 无法满足要求) @jianchao
15
+ hash: validator_1.Joi.string().optional().allow(null).default(null),
16
+ size: validator_1.Joi.number().integer().optional().allow(null).default(null),
17
+ useGlobal: validator_1.Joi.boolean().optional().default(false),
18
+ });
19
+ exports.ObjectSpaceOptionsSchema = validator_1.Joi.object({
20
+ driver: validator_1.Joi.any().required(),
21
+ spaceDid: validator_1.Joi.DID().required(),
22
+ treeRepository: validator_1.Joi.any().required(),
23
+ objectRepository: validator_1.Joi.any().required(),
24
+ objectCollectionRepository: validator_1.Joi.any().required(),
25
+ });
26
+ exports.DeleteAsOwnerOptionsSchema = validator_1.Joi.object({
27
+ key: exports.KeySchema,
28
+ });
29
+ exports.WriteOptionsSchema = validator_1.Joi.object({
30
+ appDid: validator_1.Joi.DID().required(),
31
+ key: validator_1.Joi.string().required(),
32
+ data: validator_1.Joi.any().required(),
33
+ hash: validator_1.Joi.string().optional().allow(null).default(null),
34
+ size: validator_1.Joi.number().integer().optional().allow(null).default(null),
35
+ });
36
+ exports.GetHashOptionsSchema = validator_1.Joi.object({
37
+ appDid: validator_1.Joi.DID().required(),
38
+ key: validator_1.Joi.string().required(),
39
+ });
@@ -0,0 +1,43 @@
1
+ import { Data } from '../meta';
2
+ import { DriverProtocol, WriteAsOwnerOptions } from '../protocols';
3
+ import { ObjectCollectionRepository, ObjectRepository, TreeRepository } from '../model';
4
+ export type GlobalSpaceOptions = {
5
+ driver: DriverProtocol;
6
+ treeRepository: TreeRepository;
7
+ objectRepository: ObjectRepository;
8
+ objectCollectionRepository: ObjectCollectionRepository;
9
+ gcMaxCount?: 100 | number;
10
+ gcMaxConcurrency?: 8 | number;
11
+ };
12
+ export declare class GlobalSpace {
13
+ readonly driver: DriverProtocol;
14
+ readonly treeRepository: TreeRepository;
15
+ readonly objectRepository: ObjectRepository;
16
+ readonly objectCollectionRepository: ObjectCollectionRepository;
17
+ readonly gcMaxCount: number;
18
+ readonly gcMaxConcurrency: number;
19
+ constructor(options: GlobalSpaceOptions);
20
+ /**
21
+ * @description 存储新对象到全局存储区
22
+ * @param {string} key
23
+ * @param {Data} data
24
+ * @param {WriteAsOwnerOptions} options
25
+ * @return {*} {Promise<void>}
26
+ * @memberof GlobalSpace
27
+ */
28
+ add(key: string, data: Data, options: WriteAsOwnerOptions): Promise<void>;
29
+ delete(hash: string): Promise<void>;
30
+ /**
31
+ * @description 清理未被使用的对象
32
+ * @return {Promise<void>} {Promise<void>}
33
+ * @memberof GlobalSpace
34
+ */
35
+ gc(): Promise<void>;
36
+ /**
37
+ * @description 标记一个对象,以备之后回收
38
+ * @param {...string[]} hashList
39
+ * @return {Promise<void>} {Promise<void>}
40
+ * @memberof GlobalSpace
41
+ */
42
+ mark(...hashList: string[]): Promise<void>;
43
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GlobalSpace = void 0;
16
+ const lodash_1 = require("lodash");
17
+ const mime_types_1 = __importDefault(require("mime-types"));
18
+ const debug_1 = __importDefault(require("debug"));
19
+ const p_all_1 = __importDefault(require("p-all"));
20
+ const utils_1 = require("../utils");
21
+ const global_space_1 = require("../schemas/global-space");
22
+ const schemas_1 = require("../schemas");
23
+ const debug = (0, debug_1.default)('@did-space/core:GlobalSpace');
24
+ class GlobalSpace {
25
+ constructor(options) {
26
+ debug('GlobalSpace.constructor', JSON.stringify({ options: (0, lodash_1.pick)(options, 'gcMaxCount', 'gcMaxConcurrency') }));
27
+ const { error, value } = global_space_1.GlobalSpaceOptionsSchema.validate(options);
28
+ if (error) {
29
+ throw error;
30
+ }
31
+ this.driver = value.driver;
32
+ this.treeRepository = value.treeRepository;
33
+ this.objectRepository = value.objectRepository;
34
+ this.objectCollectionRepository = value.objectCollectionRepository;
35
+ this.gcMaxCount = value.gcMaxCount;
36
+ this.gcMaxConcurrency = value.gcMaxConcurrency;
37
+ debug('GlobalSpace.constructor', JSON.stringify({ gcMaxCount: value.gcMaxCount, gcMaxConcurrency: value.gcMaxConcurrency }));
38
+ }
39
+ /**
40
+ * @description 存储新对象到全局存储区
41
+ * @param {string} key
42
+ * @param {Data} data
43
+ * @param {WriteAsOwnerOptions} options
44
+ * @return {*} {Promise<void>}
45
+ * @memberof GlobalSpace
46
+ */
47
+ add(key, data, options) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ // @note: 注意此处必须存储到全局存储区
50
+ // eslint-disable-next-line no-param-reassign
51
+ options = (0, lodash_1.merge)(options, { useGlobal: true });
52
+ debug('add.before', JSON.stringify({ key, options }));
53
+ const { error } = schemas_1.WriteAsOwnerOptionsSchema.validate(Object.assign(Object.assign({}, options), { key,
54
+ data }), { allowUnknown: true, stripUnknown: true });
55
+ if (error) {
56
+ throw error;
57
+ }
58
+ const where = {
59
+ id: options.hash,
60
+ };
61
+ debug('add.$where', JSON.stringify(where));
62
+ const objectRecord = yield this.objectRepository.findOne({
63
+ where,
64
+ raw: true,
65
+ });
66
+ debug('add.$objectRecord', JSON.stringify(objectRecord));
67
+ if (objectRecord) {
68
+ return;
69
+ }
70
+ // 存储新对象到全局存储区
71
+ const newKey = (0, utils_1.getHashPath)(options.hash);
72
+ yield this.driver.writeAsOwner(newKey, data, options);
73
+ // 添加 object 记录
74
+ yield this.objectRepository.create({
75
+ id: options.hash,
76
+ size: options.size,
77
+ meta: {
78
+ mimeType: mime_types_1.default.lookup(key) || null,
79
+ key,
80
+ },
81
+ });
82
+ debug('add.after', JSON.stringify({ objectRecord }));
83
+ });
84
+ }
85
+ delete(hash) {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ const { error } = global_space_1.HashSchema.validate(hash);
88
+ if (error) {
89
+ throw error;
90
+ }
91
+ debug('delete.before', JSON.stringify({ hash }));
92
+ const where = {
93
+ objectId: hash,
94
+ };
95
+ debug('delete.$where', JSON.stringify(where));
96
+ const count = yield this.treeRepository.count({
97
+ where,
98
+ });
99
+ debug('delete.$count', count);
100
+ if (count) {
101
+ yield this.objectCollectionRepository.destroy({ where: { id: hash } });
102
+ return;
103
+ }
104
+ yield this.driver.deleteAsOwner((0, utils_1.getHashPath)(hash), { useGlobal: true });
105
+ yield this.objectRepository.destroy({ where: { id: hash } });
106
+ yield this.objectCollectionRepository.destroy({ where: { id: hash } });
107
+ debug('delete.after', { hash });
108
+ });
109
+ }
110
+ /**
111
+ * @description 清理未被使用的对象
112
+ * @return {Promise<void>} {Promise<void>}
113
+ * @memberof GlobalSpace
114
+ */
115
+ gc() {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ debug('gc.before', 'start gc...');
118
+ const objects = yield this.objectCollectionRepository.findAll({
119
+ attributes: ['id'],
120
+ order: [['createdAt', 'ASC']],
121
+ limit: this.gcMaxCount,
122
+ });
123
+ debug('gc.$objects.length', objects.length);
124
+ const actions = objects.map((x) => {
125
+ return () => this.delete(x.id);
126
+ });
127
+ // 限制并发数量
128
+ yield (0, p_all_1.default)(actions, { concurrency: this.gcMaxConcurrency });
129
+ debug('gc.after', true);
130
+ });
131
+ }
132
+ /**
133
+ * @description 标记一个对象,以备之后回收
134
+ * @param {...string[]} hashList
135
+ * @return {Promise<void>} {Promise<void>}
136
+ * @memberof GlobalSpace
137
+ */
138
+ mark(...hashList) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ debug('mark.before', true);
141
+ debug('mark.$hashList.length', hashList.length);
142
+ yield this.objectCollectionRepository.bulkCreate(hashList.map((hash) => {
143
+ return {
144
+ id: hash,
145
+ };
146
+ }), {
147
+ ignoreDuplicates: true,
148
+ });
149
+ debug('mark.after', true);
150
+ });
151
+ }
152
+ }
153
+ exports.GlobalSpace = GlobalSpace;