@hamster-note/types 0.1.0 → 0.5.1

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.
@@ -0,0 +1,243 @@
1
+ //#region src/math/Number2.d.ts
2
+ type Number2 = {
3
+ x: number;
4
+ y: number;
5
+ };
6
+ //#endregion
7
+ //#region src/HamsterDocument/IntermediateText.d.ts
8
+ declare enum TextDir {
9
+ TTB = "ttb",
10
+ LTR = "ltr",
11
+ RTL = "rtl",
12
+ }
13
+ interface IntermediateTextSerialized {
14
+ id: string;
15
+ content: string;
16
+ fontSize: number;
17
+ fontFamily: string;
18
+ fontWeight: number;
19
+ italic: boolean;
20
+ color: string;
21
+ width: number;
22
+ height: number;
23
+ lineHeight: number;
24
+ x: number;
25
+ y: number;
26
+ ascent: number;
27
+ descent: number;
28
+ vertical?: boolean;
29
+ dir: TextDir;
30
+ rotate: number;
31
+ skew: number;
32
+ isEOL: boolean;
33
+ }
34
+ declare class IntermediateText implements IntermediateTextSerialized {
35
+ id: string;
36
+ content: string;
37
+ fontSize: number;
38
+ fontFamily: string;
39
+ fontWeight: number;
40
+ italic: boolean;
41
+ color: string;
42
+ width: number;
43
+ height: number;
44
+ lineHeight: number;
45
+ x: number;
46
+ y: number;
47
+ ascent: number;
48
+ descent: number;
49
+ vertical?: boolean;
50
+ dir: TextDir;
51
+ rotate: number;
52
+ skew: number;
53
+ isEOL: boolean;
54
+ static serialize(text: IntermediateText): IntermediateTextSerialized;
55
+ static parse(data: IntermediateTextSerialized): IntermediateText;
56
+ constructor({
57
+ id,
58
+ content,
59
+ fontSize,
60
+ fontFamily,
61
+ fontWeight,
62
+ italic,
63
+ color,
64
+ width,
65
+ height,
66
+ lineHeight,
67
+ x,
68
+ y,
69
+ ascent,
70
+ descent,
71
+ vertical,
72
+ dir,
73
+ rotate,
74
+ skew,
75
+ isEOL
76
+ }: IntermediateTextSerialized);
77
+ }
78
+ declare enum TextMarkedContentType {
79
+ BEGIN_MARKED_CONTENT = "beginMarkedContent",
80
+ BEGIN_MARKED_CONTENT_PROPS = "beginMarkedContentProps",
81
+ END_MARKED_CONTENT = "endMarkedContent",
82
+ }
83
+ declare class IntermediateTextMarkedContent extends IntermediateText {
84
+ protected type: TextMarkedContentType;
85
+ protected markedContentId: string;
86
+ constructor(data: IntermediateTextSerialized, type: TextMarkedContentType, markedContentId: string);
87
+ }
88
+ //#endregion
89
+ //#region src/HamsterDocument/IntermediatePage.d.ts
90
+ interface IntermediatePageSerialized {
91
+ id: string;
92
+ texts: IntermediateTextSerialized[];
93
+ width: number;
94
+ height: number;
95
+ number: number;
96
+ thumbnail: string | undefined;
97
+ }
98
+ type TextsGetterReturnType = Promise<IntermediateText[] | IntermediateTextSerialized[]> | IntermediateText[] | IntermediateTextSerialized[];
99
+ declare class IntermediatePage {
100
+ id: string;
101
+ texts: IntermediateText[];
102
+ width: number;
103
+ height: number;
104
+ number: number;
105
+ private _thumbnail?;
106
+ private _getThumbnailFn?;
107
+ private _getTextsFn?;
108
+ private textsLoaded;
109
+ static serialize(page: IntermediatePage): IntermediatePageSerialized;
110
+ static parse(data: IntermediatePageSerialized): IntermediatePage;
111
+ constructor({
112
+ texts,
113
+ width,
114
+ height,
115
+ number,
116
+ id,
117
+ thumbnail,
118
+ getThumbnailFn,
119
+ getTextsFn
120
+ }: Omit<IntermediatePageSerialized, 'texts'> & {
121
+ texts: IntermediateText[] | IntermediateTextSerialized[];
122
+ } & {
123
+ getThumbnailFn?: (scale: number) => Promise<string | undefined>;
124
+ getTextsFn?: () => TextsGetterReturnType;
125
+ });
126
+ getThumbnail(scale?: number): Promise<string | undefined>;
127
+ getTexts(): Promise<IntermediateText[]>;
128
+ get hasLoadedTexts(): boolean;
129
+ setGetThumbnail(fn: (scale: number) => Promise<string | undefined>): void;
130
+ setGetTexts(fn: () => TextsGetterReturnType): void;
131
+ }
132
+ //#endregion
133
+ //#region src/HamsterDocument/IntermediateOutline.d.ts
134
+ declare enum IntermediateOutlineDestType {
135
+ TEXT = "text",
136
+ PAGE = "page",
137
+ POSITION = "position",
138
+ URL = "url",
139
+ }
140
+ type IntermediateOutlineDest = IntermediateOutlineDestPage | IntermediateOutlineDestText | IntermediateOutlineDestPosition | IntermediateOutlineDestUrl;
141
+ interface IntermediateOutlineDestUrl {
142
+ targetType: IntermediateOutlineDestType.URL;
143
+ url: string;
144
+ unsafeUrl: string | undefined;
145
+ newWindow: boolean;
146
+ items?: IntermediateOutlineDest[];
147
+ }
148
+ interface IntermediateOutlineDestPage {
149
+ targetType: IntermediateOutlineDestType.PAGE;
150
+ pageId: string;
151
+ items?: IntermediateOutlineDest[];
152
+ }
153
+ interface IntermediateOutlineDestText {
154
+ targetType: IntermediateOutlineDestType.TEXT;
155
+ textId: string;
156
+ items?: IntermediateOutlineDest[];
157
+ }
158
+ interface IntermediateOutlineDestPosition {
159
+ targetType: IntermediateOutlineDestType.POSITION;
160
+ items?: IntermediateOutlineDest[];
161
+ }
162
+ interface IntermediateOutlineSerialized extends IntermediateTextSerialized {
163
+ dest: IntermediateOutlineDest;
164
+ }
165
+ declare class IntermediateOutline extends IntermediateText implements IntermediateOutlineSerialized {
166
+ dest: IntermediateOutlineDest;
167
+ static serialize(outline: IntermediateOutline): IntermediateOutlineSerialized;
168
+ static parse(data: IntermediateOutlineSerialized): IntermediateOutline;
169
+ constructor(data: IntermediateOutlineSerialized);
170
+ }
171
+ //#endregion
172
+ //#region src/HamsterDocument/IntermediateDocument.d.ts
173
+ interface IntermediateDocumentSerialized {
174
+ id: string;
175
+ pages: IntermediatePageSerialized[];
176
+ title: string;
177
+ outline?: IntermediateOutlineSerialized[];
178
+ }
179
+ type PageLoader = () => Promise<IntermediatePage>;
180
+ interface IntermediatePageEntry {
181
+ id: string;
182
+ pageNumber: number;
183
+ size: Number2;
184
+ loader: PageLoader;
185
+ cache?: Promise<IntermediatePage>;
186
+ }
187
+ declare class IntermediatePageMap {
188
+ private entryById;
189
+ private entryByPageNumber;
190
+ constructor(entries?: IntermediatePageEntry[]);
191
+ private registerEntry;
192
+ private resolve;
193
+ getPages(): Promise<IntermediatePage[]>;
194
+ updatePage(page: IntermediatePage): void;
195
+ get pageCount(): number;
196
+ get pageNumbers(): number[];
197
+ static fromSerialized(pages: IntermediatePageSerialized[]): IntermediatePageMap;
198
+ static fromInfoList(infoList: {
199
+ id: string;
200
+ pageNumber: number;
201
+ size: Number2;
202
+ getData: PageLoader;
203
+ }[]): IntermediatePageMap;
204
+ static makeBySerializedData(pages: IntermediatePageSerialized[]): IntermediatePageMap;
205
+ static makeByInfoList(infoList: {
206
+ id: string;
207
+ pageNumber: number;
208
+ size: Number2;
209
+ getData: PageLoader;
210
+ }[]): IntermediatePageMap;
211
+ getPageById(id: string): Promise<IntermediatePage> | undefined;
212
+ getPageByPageNumber(pageNumber: number): Promise<IntermediatePage> | undefined;
213
+ getPageSizeByPageNumber(pageNumber: number): Number2 | undefined;
214
+ }
215
+ declare class IntermediateDocument {
216
+ readonly id: string;
217
+ title: string;
218
+ outline?: IntermediateOutline[];
219
+ get pages(): Promise<IntermediatePage[]>;
220
+ set pages(pages: IntermediatePage[]);
221
+ private pagesMap;
222
+ static serialize(doc: IntermediateDocument): Promise<IntermediateDocumentSerialized>;
223
+ static parse(data: IntermediateDocumentSerialized): IntermediateDocument;
224
+ constructor({
225
+ pagesMap,
226
+ id,
227
+ title,
228
+ outline
229
+ }: Omit<IntermediateDocumentSerialized, 'pages'> & {
230
+ pagesMap: IntermediatePageMap;
231
+ outline?: IntermediateOutline[];
232
+ });
233
+ get pageCount(): number;
234
+ get pageNumbers(): number[];
235
+ getCover(scale?: number): Promise<string | undefined>;
236
+ getPageById(id: string): Promise<IntermediatePage> | undefined;
237
+ getPageByPageNumber(pageNumber: number): Promise<IntermediatePage> | undefined;
238
+ getPageSizeByPageNumber(pageNumber: number): Number2 | undefined;
239
+ getOutline(): IntermediateOutline[] | undefined;
240
+ }
241
+ //#endregion
242
+ export { IntermediateDocument, IntermediateDocumentSerialized, IntermediateOutline, IntermediateOutlineDest, IntermediateOutlineDestPage, IntermediateOutlineDestPosition, IntermediateOutlineDestText, IntermediateOutlineDestType, IntermediateOutlineDestUrl, IntermediateOutlineSerialized, IntermediatePage, IntermediatePageMap, IntermediatePageSerialized, IntermediateText, IntermediateTextMarkedContent, IntermediateTextSerialized, Number2, TextDir, TextMarkedContentType };
243
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,311 @@
1
+ //#region src/HamsterDocument/IntermediateText.ts
2
+ let TextDir = /* @__PURE__ */ function(TextDir$1) {
3
+ TextDir$1["TTB"] = "ttb";
4
+ TextDir$1["LTR"] = "ltr";
5
+ TextDir$1["RTL"] = "rtl";
6
+ return TextDir$1;
7
+ }({});
8
+ var IntermediateText = class IntermediateText {
9
+ id;
10
+ content;
11
+ fontSize;
12
+ fontFamily;
13
+ fontWeight;
14
+ italic;
15
+ color;
16
+ width;
17
+ height;
18
+ lineHeight;
19
+ x;
20
+ y;
21
+ ascent;
22
+ descent;
23
+ vertical;
24
+ dir;
25
+ rotate;
26
+ skew;
27
+ isEOL;
28
+ static serialize(text) {
29
+ return { ...text };
30
+ }
31
+ static parse(data) {
32
+ return new IntermediateText(data);
33
+ }
34
+ constructor({ id, content, fontSize, fontFamily, fontWeight, italic, color, width, height, lineHeight, x, y, ascent, descent, vertical, dir, rotate, skew, isEOL }) {
35
+ this.id = id;
36
+ this.content = content;
37
+ this.fontSize = fontSize;
38
+ this.fontFamily = fontFamily;
39
+ this.fontWeight = fontWeight;
40
+ this.italic = italic;
41
+ this.color = color;
42
+ this.width = width;
43
+ this.height = height;
44
+ this.lineHeight = lineHeight;
45
+ this.x = x;
46
+ this.y = y;
47
+ this.ascent = ascent;
48
+ this.descent = descent;
49
+ this.vertical = vertical;
50
+ this.dir = dir;
51
+ this.rotate = rotate;
52
+ this.skew = skew;
53
+ this.isEOL = isEOL;
54
+ }
55
+ };
56
+ let TextMarkedContentType = /* @__PURE__ */ function(TextMarkedContentType$1) {
57
+ TextMarkedContentType$1["BEGIN_MARKED_CONTENT"] = "beginMarkedContent";
58
+ TextMarkedContentType$1["BEGIN_MARKED_CONTENT_PROPS"] = "beginMarkedContentProps";
59
+ TextMarkedContentType$1["END_MARKED_CONTENT"] = "endMarkedContent";
60
+ return TextMarkedContentType$1;
61
+ }({});
62
+ var IntermediateTextMarkedContent = class extends IntermediateText {
63
+ constructor(data, type, markedContentId) {
64
+ super(data);
65
+ this.type = type;
66
+ this.markedContentId = markedContentId;
67
+ }
68
+ };
69
+
70
+ //#endregion
71
+ //#region src/HamsterDocument/IntermediatePage.ts
72
+ var IntermediatePage = class IntermediatePage {
73
+ id;
74
+ texts;
75
+ width;
76
+ height;
77
+ number;
78
+ _thumbnail;
79
+ _getThumbnailFn;
80
+ _getTextsFn;
81
+ textsLoaded;
82
+ static serialize(page) {
83
+ return {
84
+ id: page.id,
85
+ texts: page.texts.map(IntermediateText.serialize),
86
+ width: page.width,
87
+ height: page.height,
88
+ number: page.number,
89
+ thumbnail: page._thumbnail
90
+ };
91
+ }
92
+ static parse(data) {
93
+ return new IntermediatePage(data);
94
+ }
95
+ constructor({ texts, width, height, number, id, thumbnail, getThumbnailFn, getTextsFn }) {
96
+ this.id = id;
97
+ this.texts = texts.map((t) => t instanceof IntermediateText ? t : new IntermediateText(t));
98
+ this.width = width;
99
+ this.height = height;
100
+ this.number = number;
101
+ this._thumbnail = thumbnail;
102
+ if (getThumbnailFn) this._getThumbnailFn = getThumbnailFn;
103
+ if (getTextsFn) this._getTextsFn = getTextsFn;
104
+ this.textsLoaded = !getTextsFn;
105
+ }
106
+ async getThumbnail(scale = 1) {
107
+ if (this._getThumbnailFn) return this._getThumbnailFn(scale);
108
+ return this._thumbnail;
109
+ }
110
+ async getTexts() {
111
+ if (this._getTextsFn) {
112
+ this.texts = (await this._getTextsFn()).map((t) => t instanceof IntermediateText ? t : new IntermediateText(t));
113
+ this.textsLoaded = true;
114
+ this._getTextsFn = void 0;
115
+ }
116
+ return this.texts;
117
+ }
118
+ get hasLoadedTexts() {
119
+ return this.textsLoaded;
120
+ }
121
+ setGetThumbnail(fn) {
122
+ this._getThumbnailFn = fn;
123
+ }
124
+ setGetTexts(fn) {
125
+ this._getTextsFn = fn;
126
+ }
127
+ };
128
+
129
+ //#endregion
130
+ //#region src/HamsterDocument/IntermediateOutline.ts
131
+ let IntermediateOutlineDestType = /* @__PURE__ */ function(IntermediateOutlineDestType$1) {
132
+ IntermediateOutlineDestType$1["TEXT"] = "text";
133
+ IntermediateOutlineDestType$1["PAGE"] = "page";
134
+ IntermediateOutlineDestType$1["POSITION"] = "position";
135
+ IntermediateOutlineDestType$1["URL"] = "url";
136
+ return IntermediateOutlineDestType$1;
137
+ }({});
138
+ var IntermediateOutline = class IntermediateOutline extends IntermediateText {
139
+ dest;
140
+ static serialize(outline) {
141
+ return {
142
+ ...IntermediateText.serialize(outline),
143
+ dest: outline.dest
144
+ };
145
+ }
146
+ static parse(data) {
147
+ return new IntermediateOutline(data);
148
+ }
149
+ constructor(data) {
150
+ const { dest, ...textData } = data;
151
+ super(textData);
152
+ this.dest = dest;
153
+ }
154
+ };
155
+
156
+ //#endregion
157
+ //#region src/HamsterDocument/IntermediateDocument.ts
158
+ var IntermediatePageMap = class IntermediatePageMap {
159
+ entryById = /* @__PURE__ */ new Map();
160
+ entryByPageNumber = /* @__PURE__ */ new Map();
161
+ constructor(entries = []) {
162
+ entries.forEach((entry) => this.registerEntry(entry));
163
+ }
164
+ registerEntry(entry) {
165
+ this.entryById.set(entry.id, entry);
166
+ this.entryByPageNumber.set(entry.pageNumber, entry);
167
+ }
168
+ async resolve(entry) {
169
+ if (!entry.cache) entry.cache = entry.loader();
170
+ return entry.cache;
171
+ }
172
+ async getPages() {
173
+ const orderedEntries = this.pageNumbers.map((pageNumber) => this.entryByPageNumber.get(pageNumber)).filter((entry) => Boolean(entry));
174
+ return Promise.all(orderedEntries.map((entry) => this.resolve(entry)));
175
+ }
176
+ updatePage(page) {
177
+ const oldById = this.entryById.get(page.id);
178
+ if (oldById) {
179
+ this.entryByPageNumber.delete(oldById.pageNumber);
180
+ this.entryById.delete(oldById.id);
181
+ }
182
+ const oldByNumber = this.entryByPageNumber.get(page.number);
183
+ if (oldByNumber && oldByNumber.id !== page.id) {
184
+ this.entryById.delete(oldByNumber.id);
185
+ this.entryByPageNumber.delete(oldByNumber.pageNumber);
186
+ }
187
+ const newPromise = Promise.resolve(page);
188
+ const entry = {
189
+ id: page.id,
190
+ pageNumber: page.number,
191
+ size: {
192
+ x: page.width,
193
+ y: page.height
194
+ },
195
+ loader: () => newPromise,
196
+ cache: newPromise
197
+ };
198
+ this.registerEntry(entry);
199
+ }
200
+ get pageCount() {
201
+ return this.entryByPageNumber.size;
202
+ }
203
+ get pageNumbers() {
204
+ return [...this.entryByPageNumber.keys()].sort((a, b) => a - b);
205
+ }
206
+ static fromSerialized(pages) {
207
+ return new IntermediatePageMap(pages.map((page) => ({
208
+ id: page.id,
209
+ pageNumber: page.number,
210
+ loader: () => Promise.resolve(new IntermediatePage(page)),
211
+ size: {
212
+ x: page.width,
213
+ y: page.height
214
+ }
215
+ })));
216
+ }
217
+ static fromInfoList(infoList) {
218
+ return new IntermediatePageMap(infoList.map((info) => ({
219
+ id: info.id,
220
+ pageNumber: info.pageNumber,
221
+ size: info.size,
222
+ loader: info.getData
223
+ })));
224
+ }
225
+ static makeBySerializedData(pages) {
226
+ return IntermediatePageMap.fromSerialized(pages);
227
+ }
228
+ static makeByInfoList(infoList) {
229
+ return IntermediatePageMap.fromInfoList(infoList);
230
+ }
231
+ getPageById(id) {
232
+ const entry = this.entryById.get(id);
233
+ if (!entry) return void 0;
234
+ return this.resolve(entry);
235
+ }
236
+ getPageByPageNumber(pageNumber) {
237
+ const entry = this.entryByPageNumber.get(pageNumber);
238
+ if (!entry) return void 0;
239
+ return this.resolve(entry);
240
+ }
241
+ getPageSizeByPageNumber(pageNumber) {
242
+ return this.entryByPageNumber.get(pageNumber)?.size;
243
+ }
244
+ };
245
+ var IntermediateDocument = class IntermediateDocument {
246
+ id;
247
+ title;
248
+ outline;
249
+ get pages() {
250
+ return this.pagesMap.getPages();
251
+ }
252
+ set pages(pages) {
253
+ pages.forEach((page) => {
254
+ this.pagesMap.updatePage(page);
255
+ });
256
+ }
257
+ pagesMap;
258
+ static async serialize(doc) {
259
+ const pages = await doc.pagesMap.getPages();
260
+ return {
261
+ pages: await Promise.all(pages.map(async (page) => {
262
+ if (!page.hasLoadedTexts) await page.getTexts();
263
+ return IntermediatePage.serialize(page);
264
+ })),
265
+ id: doc.id,
266
+ title: doc.title,
267
+ outline: doc.outline?.map(IntermediateOutline.serialize)
268
+ };
269
+ }
270
+ static parse(data) {
271
+ return new IntermediateDocument({
272
+ ...data,
273
+ pagesMap: IntermediatePageMap.fromSerialized(data.pages),
274
+ outline: data.outline?.map(IntermediateOutline.parse)
275
+ });
276
+ }
277
+ constructor({ pagesMap, id, title, outline }) {
278
+ this.pagesMap = pagesMap;
279
+ this.id = id;
280
+ this.title = title;
281
+ this.outline = outline;
282
+ }
283
+ get pageCount() {
284
+ return this.pagesMap.pageCount;
285
+ }
286
+ get pageNumbers() {
287
+ return this.pagesMap.pageNumbers;
288
+ }
289
+ async getCover(scale = .3) {
290
+ const firstPagePromise = this.pagesMap.getPageByPageNumber(1);
291
+ const page = firstPagePromise ? await firstPagePromise : void 0;
292
+ if (!page) return void 0;
293
+ return page.getThumbnail(scale);
294
+ }
295
+ getPageById(id) {
296
+ return this.pagesMap.getPageById(id);
297
+ }
298
+ getPageByPageNumber(pageNumber) {
299
+ return this.pagesMap.getPageByPageNumber(pageNumber);
300
+ }
301
+ getPageSizeByPageNumber(pageNumber) {
302
+ return this.pagesMap.getPageSizeByPageNumber(pageNumber);
303
+ }
304
+ getOutline() {
305
+ return this.outline;
306
+ }
307
+ };
308
+
309
+ //#endregion
310
+ export { IntermediateDocument, IntermediateOutline, IntermediateOutlineDestType, IntermediatePage, IntermediatePageMap, IntermediateText, IntermediateTextMarkedContent, TextDir, TextMarkedContentType };
311
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/HamsterDocument/IntermediateText.ts","../src/HamsterDocument/IntermediatePage.ts","../src/HamsterDocument/IntermediateOutline.ts","../src/HamsterDocument/IntermediateDocument.ts"],"sourcesContent":["export enum TextDir {\n TTB = 'ttb',\n LTR = 'ltr',\n RTL = 'rtl'\n}\n\nexport interface IntermediateTextSerialized {\n id: string\n // 文字内容\n content: string\n // 字体大小,大于等于 1 的按 px 计算,小于 1 的按 em 计算\n fontSize: number\n // 字体,字体具体需要用户下载,这里只定义字体名称\n fontFamily: string\n // 字重,默认 500\n fontWeight: number\n // 是否斜体\n italic: boolean\n // 字体颜色\n color: string\n // 整体宽度\n width: number\n // 整体高度\n height: number\n // 行高\n lineHeight: number\n // x 坐标, 大于等于 1 的按 px,小于 1 的按 百分比\n x: number\n // y 坐标, 大于等于 1 的按 px,小于 1 的按 百分比\n y: number\n // 字体 baseline\n ascent: number\n // 字体 descent\n descent: number\n // 垂直文字\n vertical?: boolean\n // 文字方向\n dir: TextDir\n // 旋转\n rotate: number\n // 倾斜\n skew: number\n // 是否是行末\n isEOL: boolean\n}\n\nexport class IntermediateText implements IntermediateTextSerialized {\n public id: string\n public content: string\n public fontSize: number\n public fontFamily: string\n public fontWeight: number\n public italic: boolean\n public color: string\n public width: number\n public height: number\n public lineHeight: number\n public x: number\n public y: number\n public ascent: number\n public descent: number\n public vertical?: boolean\n public dir: TextDir\n public rotate: number\n public skew: number\n public isEOL: boolean\n static serialize(text: IntermediateText): IntermediateTextSerialized {\n return {\n ...text\n }\n }\n static parse(data: IntermediateTextSerialized): IntermediateText {\n return new IntermediateText(data)\n }\n constructor({\n id,\n content,\n fontSize,\n fontFamily,\n fontWeight,\n italic,\n color,\n width,\n height,\n lineHeight,\n x,\n y,\n ascent,\n descent,\n vertical,\n dir,\n rotate,\n skew,\n isEOL\n }: IntermediateTextSerialized) {\n this.id = id\n this.content = content\n this.fontSize = fontSize\n this.fontFamily = fontFamily\n this.fontWeight = fontWeight\n this.italic = italic\n this.color = color\n this.width = width\n this.height = height\n this.lineHeight = lineHeight\n this.x = x\n this.y = y\n this.ascent = ascent\n this.descent = descent\n this.vertical = vertical\n this.dir = dir\n this.rotate = rotate\n this.skew = skew\n this.isEOL = isEOL\n }\n}\n\nexport enum TextMarkedContentType {\n BEGIN_MARKED_CONTENT = 'beginMarkedContent',\n BEGIN_MARKED_CONTENT_PROPS = 'beginMarkedContentProps',\n END_MARKED_CONTENT = 'endMarkedContent'\n}\n\nexport class IntermediateTextMarkedContent extends IntermediateText {\n // 这两个值参见 pdfjs 的 TextMarkedContent 类型\n constructor(\n data: IntermediateTextSerialized,\n protected type: TextMarkedContentType,\n protected markedContentId: string\n ) {\n super(data)\n }\n}\n","import {\n IntermediateText,\n IntermediateTextSerialized\n} from './IntermediateText'\n\nexport interface IntermediatePageSerialized {\n id: string\n texts: IntermediateTextSerialized[]\n width: number\n height: number\n number: number\n // 缩略图,背景图\n thumbnail: string | undefined\n}\n\n// 定义文本获取函数的返回类型别名\ntype TextsGetterReturnType =\n | Promise<IntermediateText[] | IntermediateTextSerialized[]>\n | IntermediateText[]\n | IntermediateTextSerialized[]\n\nexport class IntermediatePage {\n public id: string\n public texts: IntermediateText[]\n public width: number\n public height: number\n public number: number\n private _thumbnail?: string\n private _getThumbnailFn?: (scale: number) => Promise<string | undefined>\n private _getTextsFn?: () => TextsGetterReturnType\n // 标记文本是否已经完成加载,便于上层做懒加载策略\n private textsLoaded: boolean\n static serialize(page: IntermediatePage): IntermediatePageSerialized {\n return {\n id: page.id,\n texts: page.texts.map(IntermediateText.serialize),\n width: page.width,\n height: page.height,\n number: page.number,\n // 序列化时仅保留已有的静态缩略图(如果存在)\n thumbnail: page._thumbnail\n }\n }\n static parse(data: IntermediatePageSerialized): IntermediatePage {\n return new IntermediatePage(data)\n }\n constructor({\n texts,\n width,\n height,\n number,\n id,\n thumbnail,\n getThumbnailFn,\n getTextsFn\n }: Omit<IntermediatePageSerialized, 'texts'> & {\n texts: IntermediateText[] | IntermediateTextSerialized[]\n } & {\n getThumbnailFn?: (scale: number) => Promise<string | undefined>\n getTextsFn?: () => TextsGetterReturnType\n }) {\n this.id = id\n this.texts = (\n texts as (IntermediateText | IntermediateTextSerialized)[]\n ).map((t) => (t instanceof IntermediateText ? t : new IntermediateText(t)))\n this.width = width\n this.height = height\n this.number = number\n this._thumbnail = thumbnail\n if (getThumbnailFn) this._getThumbnailFn = getThumbnailFn\n if (getTextsFn) this._getTextsFn = getTextsFn\n this.textsLoaded = !getTextsFn\n }\n // 获取缩略图,按需渲染\n async getThumbnail(scale = 1): Promise<string | undefined> {\n if (this._getThumbnailFn) return this._getThumbnailFn(scale)\n return this._thumbnail\n }\n // 获取文本,按需获取\n async getTexts(): Promise<IntermediateText[]> {\n if (this._getTextsFn) {\n const data = await this._getTextsFn()\n const mapped = (\n data as (IntermediateText | IntermediateTextSerialized)[]\n ).map((t) =>\n t instanceof IntermediateText ? t : new IntermediateText(t)\n )\n this.texts = mapped\n this.textsLoaded = true\n // 懒加载完成后去掉取数函数,避免重复请求\n this._getTextsFn = undefined\n }\n return this.texts\n }\n // 判断文本是否已加载(便于调用方做缓存判断)\n get hasLoadedTexts(): boolean {\n return this.textsLoaded\n }\n // 提供一个方法以注入按需生成缩略图的函数\n setGetThumbnail(fn: (scale: number) => Promise<string | undefined>) {\n this._getThumbnailFn = fn\n }\n // 提供一个方法以注入按需获取文本的函数\n setGetTexts(fn: () => TextsGetterReturnType) {\n this._getTextsFn = fn\n }\n}\n","import {\n IntermediateText,\n IntermediateTextSerialized\n} from './IntermediateText'\n\nexport enum IntermediateOutlineDestType {\n TEXT = 'text',\n PAGE = 'page',\n POSITION = 'position',\n URL = 'url'\n}\n\nexport type IntermediateOutlineDest =\n | IntermediateOutlineDestPage\n | IntermediateOutlineDestText\n | IntermediateOutlineDestPosition\n | IntermediateOutlineDestUrl\n\nexport interface IntermediateOutlineDestUrl {\n targetType: IntermediateOutlineDestType.URL\n url: string\n unsafeUrl: string | undefined\n newWindow: boolean\n items?: IntermediateOutlineDest[]\n}\n\nexport interface IntermediateOutlineDestPage {\n targetType: IntermediateOutlineDestType.PAGE\n pageId: string\n items?: IntermediateOutlineDest[]\n}\n\nexport interface IntermediateOutlineDestText {\n targetType: IntermediateOutlineDestType.TEXT\n textId: string\n items?: IntermediateOutlineDest[]\n}\n\nexport interface IntermediateOutlineDestPosition {\n targetType: IntermediateOutlineDestType.POSITION\n items?: IntermediateOutlineDest[]\n}\n\nexport interface IntermediateOutlineSerialized extends IntermediateTextSerialized {\n dest: IntermediateOutlineDest\n}\n\nexport class IntermediateOutline\n extends IntermediateText\n implements IntermediateOutlineSerialized\n{\n public dest: IntermediateOutlineDest\n static serialize(\n outline: IntermediateOutline\n ): IntermediateOutlineSerialized {\n return {\n ...IntermediateText.serialize(outline),\n dest: outline.dest\n }\n }\n static parse(data: IntermediateOutlineSerialized): IntermediateOutline {\n return new IntermediateOutline(data)\n }\n constructor(data: IntermediateOutlineSerialized) {\n const { dest, ...textData } = data\n super(textData as IntermediateTextSerialized)\n this.dest = dest\n }\n}\n","import {\n IntermediatePage,\n IntermediatePageSerialized\n} from './IntermediatePage'\nimport {\n IntermediateOutline,\n IntermediateOutlineSerialized\n} from './IntermediateOutline'\nimport { Number2 } from '../math/index'\n\nexport interface IntermediateDocumentSerialized {\n id: string\n pages: IntermediatePageSerialized[]\n title: string\n // 文档大纲(可选)\n outline?: IntermediateOutlineSerialized[]\n}\n\ntype PageLoader = () => Promise<IntermediatePage>\n\ninterface IntermediatePageEntry {\n id: string\n pageNumber: number\n size: Number2\n loader: PageLoader\n cache?: Promise<IntermediatePage>\n}\n\n// ! 用来懒加载 Pages\nexport class IntermediatePageMap {\n // ! 以 id、页码分别索引,方便不同场景快速查找\n private entryById: Map<string, IntermediatePageEntry> = new Map()\n private entryByPageNumber: Map<number, IntermediatePageEntry> = new Map()\n\n constructor(entries: IntermediatePageEntry[] = []) {\n entries.forEach((entry) => this.registerEntry(entry))\n }\n\n private registerEntry(entry: IntermediatePageEntry) {\n this.entryById.set(entry.id, entry)\n this.entryByPageNumber.set(entry.pageNumber, entry)\n }\n\n private async resolve(\n entry: IntermediatePageEntry\n ): Promise<IntermediatePage> {\n if (!entry.cache) entry.cache = entry.loader()\n return entry.cache\n }\n\n // 按页码顺序批量获取,内部并发取数避免串行等待\n async getPages(): Promise<IntermediatePage[]> {\n const orderedEntries = this.pageNumbers\n .map((pageNumber) => this.entryByPageNumber.get(pageNumber))\n .filter((entry): entry is IntermediatePageEntry => Boolean(entry))\n return Promise.all(orderedEntries.map((entry) => this.resolve(entry)))\n }\n\n // 直接用完整实例覆盖缓存,便于外部更新\n updatePage(page: IntermediatePage) {\n // 先清理旧索引,避免相同 id 或页码残留造成脏数据\n const oldById = this.entryById.get(page.id)\n if (oldById) {\n this.entryByPageNumber.delete(oldById.pageNumber)\n this.entryById.delete(oldById.id)\n }\n const oldByNumber = this.entryByPageNumber.get(page.number)\n if (oldByNumber && oldByNumber.id !== page.id) {\n this.entryById.delete(oldByNumber.id)\n this.entryByPageNumber.delete(oldByNumber.pageNumber)\n }\n const newPromise = Promise.resolve(page)\n const entry: IntermediatePageEntry = {\n id: page.id,\n pageNumber: page.number,\n size: { x: page.width, y: page.height },\n loader: () => newPromise,\n cache: newPromise\n }\n this.registerEntry(entry)\n }\n\n get pageCount() {\n return this.entryByPageNumber.size\n }\n\n get pageNumbers(): number[] {\n return [...this.entryByPageNumber.keys()].sort((a, b) => a - b)\n }\n\n // & 从序列化的数据生成类\n static fromSerialized(pages: IntermediatePageSerialized[]) {\n const entries: IntermediatePageEntry[] = pages.map((page) => ({\n id: page.id,\n pageNumber: page.number,\n loader: () => Promise.resolve(new IntermediatePage(page)),\n size: { x: page.width, y: page.height }\n }))\n return new IntermediatePageMap(entries)\n }\n\n // & 从列表数据生成类\n static fromInfoList(\n infoList: {\n id: string\n pageNumber: number\n size: Number2\n getData: PageLoader\n }[]\n ) {\n const entries: IntermediatePageEntry[] = infoList.map((info) => ({\n id: info.id,\n pageNumber: info.pageNumber,\n size: info.size,\n loader: info.getData\n }))\n return new IntermediatePageMap(entries)\n }\n\n // 兼容旧命名(Deprecated),方便平滑过渡\n static makeBySerializedData(pages: IntermediatePageSerialized[]) {\n return IntermediatePageMap.fromSerialized(pages)\n }\n static makeByInfoList(\n infoList: {\n id: string\n pageNumber: number\n size: Number2\n getData: PageLoader\n }[]\n ) {\n return IntermediatePageMap.fromInfoList(infoList)\n }\n\n getPageById(id: string) {\n const entry = this.entryById.get(id)\n if (!entry) return undefined\n return this.resolve(entry)\n }\n\n getPageByPageNumber(pageNumber: number) {\n const entry = this.entryByPageNumber.get(pageNumber)\n if (!entry) return undefined\n return this.resolve(entry)\n }\n\n getPageSizeByPageNumber(pageNumber: number) {\n return this.entryByPageNumber.get(pageNumber)?.size\n }\n}\n\nexport class IntermediateDocument {\n public readonly id: string\n public title: string\n public outline?: IntermediateOutline[]\n\n get pages(): Promise<IntermediatePage[]> {\n return this.pagesMap.getPages()\n }\n\n set pages(pages: IntermediatePage[]) {\n pages.forEach((page) => {\n this.pagesMap.updatePage(page)\n })\n }\n\n private pagesMap: IntermediatePageMap\n\n static async serialize(\n doc: IntermediateDocument\n ): Promise<IntermediateDocumentSerialized> {\n const pages = await doc.pagesMap.getPages()\n const serializedPages = await Promise.all(\n pages.map(async (page) => {\n if (!page.hasLoadedTexts) await page.getTexts()\n return IntermediatePage.serialize(page)\n })\n )\n return {\n pages: serializedPages,\n id: doc.id,\n title: doc.title,\n outline: doc.outline?.map(IntermediateOutline.serialize)\n }\n }\n\n static parse(data: IntermediateDocumentSerialized): IntermediateDocument {\n return new IntermediateDocument({\n ...data,\n pagesMap: IntermediatePageMap.fromSerialized(data.pages),\n outline: data.outline?.map(IntermediateOutline.parse)\n })\n }\n\n constructor({\n pagesMap,\n id,\n title,\n outline\n }: Omit<IntermediateDocumentSerialized, 'pages'> & {\n pagesMap: IntermediatePageMap\n outline?: IntermediateOutline[]\n }) {\n this.pagesMap = pagesMap\n this.id = id\n this.title = title\n this.outline = outline\n }\n\n get pageCount() {\n return this.pagesMap.pageCount\n }\n\n get pageNumbers() {\n return this.pagesMap.pageNumbers\n }\n\n async getCover(scale = 0.3) {\n const firstPagePromise = this.pagesMap.getPageByPageNumber(1)\n const page = firstPagePromise ? await firstPagePromise : undefined\n if (!page) return undefined\n return page.getThumbnail(scale)\n }\n\n getPageById(id: string) {\n return this.pagesMap.getPageById(id)\n }\n\n getPageByPageNumber(pageNumber: number) {\n return this.pagesMap.getPageByPageNumber(pageNumber)\n }\n\n getPageSizeByPageNumber(pageNumber: number) {\n return this.pagesMap.getPageSizeByPageNumber(pageNumber)\n }\n\n // 获取文档大纲\n getOutline() {\n return this.outline\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@hamster-note/types",
3
- "version": "0.1.0",
3
+ "version": "0.5.1",
4
4
  "description": "",
5
5
  "scripts": {
6
- "build:all": "echo no-build",
6
+ "build:all": "rolldown --config rolldown.config.ts",
7
+ "prepublishOnly": "yarn build:all",
8
+ "lint": "echo 'no-lint'",
7
9
  "test": "echo 'no-test'"
8
10
  },
9
11
  "dependencies": {},
@@ -22,14 +24,23 @@
22
24
  "globals": "^15.14.0",
23
25
  "prettier": "^3.7.4",
24
26
  "prettier-config-standard": "^7.0.0",
27
+ "rolldown": "^1.0.0-beta.58",
28
+ "rolldown-plugin-dts": "^0.20.0",
25
29
  "typescript": "^5.0.2",
26
30
  "typescript-eslint": "^8.50.0"
27
31
  },
28
- "main": "src/index.ts",
29
- "module": "src/index.ts",
30
- "types": "src/index.ts",
32
+ "type": "module",
33
+ "main": "dist/index.js",
34
+ "module": "dist/index.js",
35
+ "types": "dist/index.d.ts",
36
+ "exports": {
37
+ ".": {
38
+ "import": "./dist/index.js",
39
+ "types": "./dist/index.d.ts"
40
+ }
41
+ },
31
42
  "files": [
32
- "src"
43
+ "dist"
33
44
  ],
34
45
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
35
- }
46
+ }
@@ -1,199 +0,0 @@
1
- import {
2
- IntermediatePage,
3
- IntermediatePageSerialized
4
- } from './IntermediatePage'
5
- import {
6
- IntermediateOutline,
7
- IntermediateOutlineSerialized
8
- } from './IntermediateOutline'
9
- import { Number2 } from 'src/math'
10
-
11
- export interface IntermediateDocumentSerialized {
12
- id: string
13
- pages: IntermediatePageSerialized[]
14
- title: string
15
- // 文档大纲(可选)
16
- outline?: IntermediateOutlineSerialized[]
17
- }
18
-
19
- type getPage = () => Promise<IntermediatePage>
20
-
21
- // ! 用来懒加载 Pages
22
- export class IntermediatePageMap {
23
- // ! 缓存 Promise
24
- private cacheMapById: Map<string, ReturnType<getPage>> = new Map()
25
- // ! 缓存 Promise
26
- private cacheMapByPageNumber: Map<number, ReturnType<getPage>> = new Map()
27
- constructor(
28
- private mapById: Map<string, getPage>,
29
- private mapByPageNumber: Map<number, getPage>,
30
- private sizeMapByPageNumber: Map<number, Number2>
31
- ) {
32
- return
33
- }
34
- // 按顺序从第一页开始
35
- async getPages(): Promise<IntermediatePage[]> {
36
- const result: IntermediatePage[] = []
37
- for (const pageId of this.mapById.keys()) {
38
- // ? 从 this.getPageById 拿是因为会过一遍缓存
39
- const getPage = this.getPageById(pageId)
40
- if (getPage) {
41
- const page = await getPage()
42
- result[page.number - 1] = page
43
- }
44
- }
45
- return result
46
- }
47
- updatePage(page: IntermediatePage) {
48
- const newPromise = Promise.resolve(page)
49
- const newGetPage = () => newPromise
50
- this.cacheMapById.set(page.id, newPromise)
51
- this.cacheMapByPageNumber.set(page.number, newPromise)
52
- this.mapById.set(page.id, newGetPage)
53
- this.mapByPageNumber.set(page.number, newGetPage)
54
- this.sizeMapByPageNumber.set(page.number, {
55
- x: page.width,
56
- y: page.height
57
- })
58
- }
59
- // & 从序列化的数据生成类
60
- static makeBySerializedData(pages: IntermediatePageSerialized[]) {
61
- const mapById: IntermediatePageMap['mapById'] = new Map()
62
- const mapByPageNumber: IntermediatePageMap['mapByPageNumber'] = new Map()
63
- const sizeMapByPageNumber: IntermediatePageMap['sizeMapByPageNumber'] =
64
- new Map()
65
- pages.forEach((page) => {
66
- mapById.set(page.id, () => Promise.resolve(new IntermediatePage(page)))
67
- mapByPageNumber.set(page.number, () =>
68
- Promise.resolve(new IntermediatePage(page))
69
- )
70
- sizeMapByPageNumber.set(page.number, { x: page.width, y: page.height })
71
- })
72
- return new IntermediatePageMap(
73
- mapById,
74
- mapByPageNumber,
75
- sizeMapByPageNumber
76
- )
77
- }
78
- // & 从列表数据生成类
79
- static makeByInfoList(
80
- infoList: {
81
- id: string
82
- pageNumber: number
83
- size: Number2
84
- getData: getPage
85
- }[]
86
- ) {
87
- const mapById: IntermediatePageMap['mapById'] = new Map()
88
- const mapByPageNumber: IntermediatePageMap['mapByPageNumber'] = new Map()
89
- const sizeMapByPageNumber: IntermediatePageMap['sizeMapByPageNumber'] =
90
- new Map()
91
- infoList.forEach((info) => {
92
- mapById.set(info.id, info.getData)
93
- mapByPageNumber.set(info.pageNumber, info.getData)
94
- sizeMapByPageNumber.set(info.pageNumber, info.size)
95
- })
96
- return new IntermediatePageMap(
97
- mapById,
98
- mapByPageNumber,
99
- sizeMapByPageNumber
100
- )
101
- }
102
- getPageById(id: string) {
103
- const cache = this.cacheMapById.get(id)
104
- if (!cache) {
105
- const result = this.mapById.get(id)
106
- if (result) {
107
- const promise = result()
108
- this.cacheMapById.set(id, promise)
109
- return () => promise
110
- }
111
- } else {
112
- return () => cache
113
- }
114
- return undefined
115
- }
116
- getPageByPageNumber(pageNumber: number) {
117
- const cache = this.cacheMapByPageNumber.get(pageNumber)
118
- if (!cache) {
119
- const result = this.mapByPageNumber.get(pageNumber)
120
- if (result) {
121
- const promise = result()
122
- this.cacheMapByPageNumber.set(pageNumber, promise)
123
- return () => promise
124
- }
125
- } else {
126
- return () => cache
127
- }
128
- return undefined
129
- }
130
- getPageSizeByPageNumber(pageNumber: number) {
131
- return this.sizeMapByPageNumber.get(pageNumber)
132
- }
133
- }
134
-
135
- export class IntermediateDocument {
136
- public id: string
137
- public title: string
138
- public outline?: IntermediateOutline[]
139
- get pages(): Promise<IntermediatePage[]> {
140
- // 按顺序从 pagesMap 获取pages
141
- return this.pagesMap.getPages()
142
- }
143
- set pages(pages: IntermediatePage[]) {
144
- pages.forEach((page) => {
145
- this.pagesMap.updatePage(page)
146
- })
147
- }
148
- private pagesMap: IntermediatePageMap
149
- static async serialize(
150
- doc: IntermediateDocument
151
- ): Promise<IntermediateDocumentSerialized> {
152
- const pages = await doc.pages
153
- return {
154
- pages: pages.map(IntermediatePage.serialize),
155
- id: doc.id,
156
- title: doc.title,
157
- outline: doc.outline?.map(IntermediateOutline.serialize)
158
- }
159
- }
160
- static parse(data: IntermediateDocumentSerialized): IntermediateDocument {
161
- return new IntermediateDocument({
162
- ...data,
163
- pagesMap: IntermediatePageMap.makeBySerializedData(data.pages),
164
- outline: data.outline?.map(IntermediateOutline.parse)
165
- })
166
- }
167
- constructor({
168
- pagesMap,
169
- id,
170
- title,
171
- outline
172
- }: Omit<IntermediateDocumentSerialized, 'pages'> & {
173
- pagesMap: IntermediatePageMap
174
- outline?: IntermediateOutline[]
175
- }) {
176
- this.pagesMap = pagesMap
177
- this.id = id
178
- this.title = title
179
- this.outline = outline
180
- }
181
- async getCover() {
182
- const page = await this.pagesMap.getPageByPageNumber(1)?.()
183
- if (!page) return undefined
184
- return page.getThumbnail(0.3)
185
- }
186
- getPageById(id: string) {
187
- return this.pagesMap.getPageById(id)
188
- }
189
- getPageByPageNumber(pageNumber: number) {
190
- return this.pagesMap.getPageByPageNumber(pageNumber)
191
- }
192
- getPageSizeByPageNumber(pageNumber: number) {
193
- return this.pagesMap.getPageSizeByPageNumber(pageNumber)
194
- }
195
- // 获取文档大纲
196
- getOutline() {
197
- return this.outline
198
- }
199
- }
@@ -1,69 +0,0 @@
1
- import {
2
- IntermediateText,
3
- IntermediateTextSerialized
4
- } from './IntermediateText'
5
-
6
- export enum IntermediateOutlineDestType {
7
- TEXT = 'text',
8
- PAGE = 'page',
9
- POSITION = 'position',
10
- URL = 'url'
11
- }
12
-
13
- export type IntermediateOutlineDest =
14
- | IntermediateOutlineDestPage
15
- | IntermediateOutlineDestText
16
- | IntermediateOutlineDestPosition
17
- | IntermediateOutlineDestUrl
18
-
19
- export interface IntermediateOutlineDestUrl {
20
- targetType: IntermediateOutlineDestType.URL
21
- url: string
22
- unsafeUrl: string | undefined
23
- newWindow: boolean
24
- items?: IntermediateOutlineDest[]
25
- }
26
-
27
- export interface IntermediateOutlineDestPage {
28
- targetType: IntermediateOutlineDestType.PAGE
29
- pageId: string
30
- items?: IntermediateOutlineDest[]
31
- }
32
-
33
- export interface IntermediateOutlineDestText {
34
- targetType: IntermediateOutlineDestType.TEXT
35
- textId: string
36
- items?: IntermediateOutlineDest[]
37
- }
38
-
39
- export interface IntermediateOutlineDestPosition {
40
- targetType: IntermediateOutlineDestType.POSITION
41
- items?: IntermediateOutlineDest[]
42
- }
43
-
44
- export interface IntermediateOutlineSerialized extends IntermediateTextSerialized {
45
- dest: IntermediateOutlineDest
46
- }
47
-
48
- export class IntermediateOutline
49
- extends IntermediateText
50
- implements IntermediateOutlineSerialized
51
- {
52
- public dest: IntermediateOutlineDest
53
- static serialize(
54
- outline: IntermediateOutline
55
- ): IntermediateOutlineSerialized {
56
- return {
57
- ...IntermediateText.serialize(outline),
58
- dest: outline.dest
59
- }
60
- }
61
- static parse(data: IntermediateOutlineSerialized): IntermediateOutline {
62
- return new IntermediateOutline(data)
63
- }
64
- constructor(data: IntermediateOutlineSerialized) {
65
- const { dest, ...textData } = data
66
- super(textData as IntermediateTextSerialized)
67
- this.dest = dest
68
- }
69
- }
@@ -1,97 +0,0 @@
1
- import {
2
- IntermediateText,
3
- IntermediateTextSerialized
4
- } from './IntermediateText'
5
-
6
- export interface IntermediatePageSerialized {
7
- id: string
8
- texts: IntermediateTextSerialized[]
9
- width: number
10
- height: number
11
- number: number
12
- // 缩略图,背景图
13
- thumbnail: string | undefined
14
- }
15
-
16
- // 定义文本获取函数的返回类型别名
17
- type TextsGetterReturnType =
18
- | Promise<IntermediateText[] | IntermediateTextSerialized[]>
19
- | IntermediateText[]
20
- | IntermediateTextSerialized[]
21
-
22
- export class IntermediatePage {
23
- public id: string
24
- public texts: IntermediateText[]
25
- public width: number
26
- public height: number
27
- public number: number
28
- private _thumbnail?: string
29
- private _getThumbnailFn?: (scale: number) => Promise<string | undefined>
30
- private _getTextsFn?: () => TextsGetterReturnType
31
- static serialize(page: IntermediatePage): IntermediatePageSerialized {
32
- return {
33
- id: page.id,
34
- texts: page.texts.map(IntermediateText.serialize),
35
- width: page.width,
36
- height: page.height,
37
- number: page.number,
38
- // 序列化时仅保留已有的静态缩略图(如果存在)
39
- thumbnail: page._thumbnail
40
- }
41
- }
42
- static parse(data: IntermediatePageSerialized): IntermediatePage {
43
- return new IntermediatePage(data)
44
- }
45
- constructor({
46
- texts,
47
- width,
48
- height,
49
- number,
50
- id,
51
- thumbnail,
52
- getThumbnailFn,
53
- getTextsFn
54
- }: Omit<IntermediatePageSerialized, 'texts'> & {
55
- texts: IntermediateText[] | IntermediateTextSerialized[]
56
- } & {
57
- getThumbnailFn?: (scale: number) => Promise<string | undefined>
58
- getTextsFn?: () => TextsGetterReturnType
59
- }) {
60
- this.id = id
61
- this.texts = (
62
- texts as (IntermediateText | IntermediateTextSerialized)[]
63
- ).map((t) => (t instanceof IntermediateText ? t : new IntermediateText(t)))
64
- this.width = width
65
- this.height = height
66
- this.number = number
67
- this._thumbnail = thumbnail
68
- if (getThumbnailFn) this._getThumbnailFn = getThumbnailFn
69
- if (getTextsFn) this._getTextsFn = getTextsFn
70
- }
71
- // 获取缩略图,按需渲染
72
- async getThumbnail(scale = 1): Promise<string | undefined> {
73
- if (this._getThumbnailFn) return this._getThumbnailFn(scale)
74
- return this._thumbnail
75
- }
76
- // 获取文本,按需获取
77
- async getTexts(): Promise<IntermediateText[]> {
78
- if (this._getTextsFn) {
79
- const data = await this._getTextsFn()
80
- const mapped = (
81
- data as (IntermediateText | IntermediateTextSerialized)[]
82
- ).map((t) =>
83
- t instanceof IntermediateText ? t : new IntermediateText(t)
84
- )
85
- this.texts = mapped
86
- }
87
- return this.texts
88
- }
89
- // 提供一个方法以注入按需生成缩略图的函数
90
- setGetThumbnail(fn: (scale: number) => Promise<string | undefined>) {
91
- this._getThumbnailFn = fn
92
- }
93
- // 提供一个方法以注入按需获取文本的函数
94
- setGetTexts(fn: () => TextsGetterReturnType) {
95
- this._getTextsFn = fn
96
- }
97
- }
@@ -1,133 +0,0 @@
1
- export enum TextDir {
2
- TTB = 'ttb',
3
- LTR = 'ltr',
4
- RTL = 'rtl'
5
- }
6
-
7
- export interface IntermediateTextSerialized {
8
- id: string
9
- // 文字内容
10
- content: string
11
- // 字体大小,大于等于 1 的按 px 计算,小于 1 的按 em 计算
12
- fontSize: number
13
- // 字体,字体具体需要用户下载,这里只定义字体名称
14
- fontFamily: string
15
- // 字重,默认 500
16
- fontWeight: number
17
- // 是否斜体
18
- italic: boolean
19
- // 字体颜色
20
- color: string
21
- // 整体宽度
22
- width: number
23
- // 整体高度
24
- height: number
25
- // 行高
26
- lineHeight: number
27
- // x 坐标, 大于等于 1 的按 px,小于 1 的按 百分比
28
- x: number
29
- // y 坐标, 大于等于 1 的按 px,小于 1 的按 百分比
30
- y: number
31
- // 字体 baseline
32
- ascent: number
33
- // 字体 descent
34
- descent: number
35
- // 垂直文字
36
- vertical?: boolean
37
- // 文字方向
38
- dir: TextDir
39
- // 旋转
40
- rotate: number
41
- // 倾斜
42
- skew: number
43
- // 是否是行末
44
- isEOL: boolean
45
- }
46
-
47
- export class IntermediateText implements IntermediateTextSerialized {
48
- public id: string
49
- public content: string
50
- public fontSize: number
51
- public fontFamily: string
52
- public fontWeight: number
53
- public italic: boolean
54
- public color: string
55
- public width: number
56
- public height: number
57
- public lineHeight: number
58
- public x: number
59
- public y: number
60
- public ascent: number
61
- public descent: number
62
- public vertical?: boolean
63
- public dir: TextDir
64
- public rotate: number
65
- public skew: number
66
- public isEOL: boolean
67
- static serialize(text: IntermediateText): IntermediateTextSerialized {
68
- return {
69
- ...text
70
- }
71
- }
72
- static parse(data: IntermediateTextSerialized): IntermediateText {
73
- return new IntermediateText(data)
74
- }
75
- constructor({
76
- id,
77
- content,
78
- fontSize,
79
- fontFamily,
80
- fontWeight,
81
- italic,
82
- color,
83
- width,
84
- height,
85
- lineHeight,
86
- x,
87
- y,
88
- ascent,
89
- descent,
90
- vertical,
91
- dir,
92
- rotate,
93
- skew,
94
- isEOL
95
- }: IntermediateTextSerialized) {
96
- this.id = id
97
- this.content = content
98
- this.fontSize = fontSize
99
- this.fontFamily = fontFamily
100
- this.fontWeight = fontWeight
101
- this.italic = italic
102
- this.color = color
103
- this.width = width
104
- this.height = height
105
- this.lineHeight = lineHeight
106
- this.x = x
107
- this.y = y
108
- this.ascent = ascent
109
- this.descent = descent
110
- this.vertical = vertical
111
- this.dir = dir
112
- this.rotate = rotate
113
- this.skew = skew
114
- this.isEOL = isEOL
115
- }
116
- }
117
-
118
- export enum TextMarkedContentType {
119
- BEGIN_MARKED_CONTENT = 'beginMarkedContent',
120
- BEGIN_MARKED_CONTENT_PROPS = 'beginMarkedContentProps',
121
- END_MARKED_CONTENT = 'endMarkedContent'
122
- }
123
-
124
- export class IntermediateTextMarkedContent extends IntermediateText {
125
- // 这两个值参见 pdfjs 的 TextMarkedContent 类型
126
- constructor(
127
- data: IntermediateTextSerialized,
128
- protected type: TextMarkedContentType,
129
- protected markedContentId: string
130
- ) {
131
- super(data)
132
- }
133
- }
@@ -1,4 +0,0 @@
1
- export * from './IntermediateDocument'
2
- export * from './IntermediatePage'
3
- export * from './IntermediateText'
4
- export * from './IntermediateOutline'
@@ -1,8 +0,0 @@
1
- ---
2
- globs: common/api/main/dto/*.ts
3
- alwaysApply: false
4
- ---
5
- 1. 当前文件夹是用来放置接口传参类型的
6
- 2. 这个文件夹前后端都会引用,在创作时要同时兼容浏览器和 NodeJs
7
- 3. 所有字段必须有中文注释
8
- 4. 在编辑这个文件夹里面的文件时,要注意对应的后端是 NestJs,如果是在 NestJs 中嵌入时,要注意对应格式符合 NestJs 要求
@@ -1,3 +0,0 @@
1
- export interface BatchUpdateDto {
2
- uuids: string[]
3
- }
@@ -1,17 +0,0 @@
1
- export interface CreateFolderDto {
2
- name: string
3
-
4
- // 父文件夹 uuid,可选;不传表示顶层
5
- parentUuid?: string
6
-
7
- // 预留:标签与颜色
8
- tags?: string
9
-
10
- color?: string
11
-
12
- // 排序方式 JSON(预留)
13
- sortOptions?: Record<string, object>
14
-
15
- // 排序权重(默认 0)
16
- order?: number
17
- }
@@ -1,18 +0,0 @@
1
- export interface CreateUserDto {
2
- // 用户名:仅展示用途,可选,可重复
3
- username?: string
4
-
5
- password: string
6
-
7
- // 手机号:非必填
8
- phone?: string
9
-
10
- email: string
11
-
12
- // 邮箱验证码(注册必填)
13
- emailCode: string
14
-
15
- avatar?: string
16
-
17
- wechatId?: string
18
- }
@@ -1,5 +0,0 @@
1
- export interface InitUploadDto {
2
- originalFilename: string
3
-
4
- size: number // bytes, max 1GB
5
- }
@@ -1,14 +0,0 @@
1
- export type UploadStatus = 'uploading' | 'completed' | 'failed'
2
-
3
- export interface ListFilesQueryDto {
4
- // 父级文件夹 uuid;不传表示不按层级过滤,传空/"null"/空字符串表示顶层
5
- parentUuid?: string
6
-
7
- // 过滤上传状态(uploading/completed/failed)
8
- status?: UploadStatus
9
-
10
- // 分页参数
11
- page?: number
12
-
13
- pageSize?: number
14
- }
@@ -1,14 +0,0 @@
1
- export interface UpdateFolderDto {
2
- name?: string
3
-
4
- tags?: string
5
-
6
- color?: string
7
-
8
- sortOptions?: Record<string, object> | null
9
-
10
- order?: number
11
-
12
- // 允许移动到另一个父级
13
- parentUuid?: string | null
14
- }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './math'
2
- export * from './HamsterDocument'
@@ -1 +0,0 @@
1
- export type Number2 = { x: number; y: number }
package/src/math/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './Number2'