@zlooks.cn/blog-server 1.0.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/dist/blog/blog-application.d.ts +153 -0
- package/dist/blog/blog-application.d.ts.map +1 -0
- package/dist/blog/blog-application.js +115 -0
- package/dist/blog/blog-application.js.map +1 -0
- package/dist/blog/comment-client-metadata.d.ts +19 -0
- package/dist/blog/comment-client-metadata.d.ts.map +1 -0
- package/dist/blog/comment-client-metadata.js +78 -0
- package/dist/blog/comment-client-metadata.js.map +1 -0
- package/dist/blog/errors.d.ts +12 -0
- package/dist/blog/errors.d.ts.map +1 -0
- package/dist/blog/errors.js +21 -0
- package/dist/blog/errors.js.map +1 -0
- package/dist/blog/micro-user-directory.d.ts +11 -0
- package/dist/blog/micro-user-directory.d.ts.map +1 -0
- package/dist/blog/micro-user-directory.js +18 -0
- package/dist/blog/micro-user-directory.js.map +1 -0
- package/dist/blog/post-content-audit.d.ts +34 -0
- package/dist/blog/post-content-audit.d.ts.map +1 -0
- package/dist/blog/post-content-audit.js +190 -0
- package/dist/blog/post-content-audit.js.map +1 -0
- package/dist/blog/post-view-cache.d.ts +15 -0
- package/dist/blog/post-view-cache.d.ts.map +1 -0
- package/dist/blog/post-view-cache.js +23 -0
- package/dist/blog/post-view-cache.js.map +1 -0
- package/dist/blog/public-blog-micro.d.ts +291 -0
- package/dist/blog/public-blog-micro.d.ts.map +1 -0
- package/dist/blog/public-blog-micro.js +71 -0
- package/dist/blog/public-blog-micro.js.map +1 -0
- package/dist/blog/public-blog-service.d.ts +104 -0
- package/dist/blog/public-blog-service.d.ts.map +1 -0
- package/dist/blog/public-blog-service.js +341 -0
- package/dist/blog/public-blog-service.js.map +1 -0
- package/dist/browser-api/dispatch-stream.d.ts +5 -0
- package/dist/browser-api/dispatch-stream.d.ts.map +1 -0
- package/dist/browser-api/dispatch-stream.js +4 -0
- package/dist/browser-api/dispatch-stream.js.map +1 -0
- package/dist/browser-api/dispatcher.d.ts +15 -0
- package/dist/browser-api/dispatcher.d.ts.map +1 -0
- package/dist/browser-api/dispatcher.js +145 -0
- package/dist/browser-api/dispatcher.js.map +1 -0
- package/dist/browser-api/provider-publisher.d.ts +24 -0
- package/dist/browser-api/provider-publisher.d.ts.map +1 -0
- package/dist/browser-api/provider-publisher.js +107 -0
- package/dist/browser-api/provider-publisher.js.map +1 -0
- package/dist/command/index.d.ts +3 -0
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +24 -0
- package/dist/command/index.js.map +1 -0
- package/dist/config/schema.d.ts +25 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/identity.d.ts +2 -0
- package/dist/contracts/identity.d.ts.map +1 -0
- package/dist/contracts/identity.js +2 -0
- package/dist/contracts/identity.js.map +1 -0
- package/dist/contracts/mcp.d.ts +69 -0
- package/dist/contracts/mcp.d.ts.map +1 -0
- package/dist/contracts/mcp.js +41 -0
- package/dist/contracts/mcp.js.map +1 -0
- package/dist/contracts/public-api.d.ts +3 -0
- package/dist/contracts/public-api.d.ts.map +1 -0
- package/dist/contracts/public-api.js +2 -0
- package/dist/contracts/public-api.js.map +1 -0
- package/dist/mcp/blog-prompts.d.ts +135 -0
- package/dist/mcp/blog-prompts.d.ts.map +1 -0
- package/dist/mcp/blog-prompts.js +107 -0
- package/dist/mcp/blog-prompts.js.map +1 -0
- package/dist/mcp/blog-provider.d.ts +4 -0
- package/dist/mcp/blog-provider.d.ts.map +1 -0
- package/dist/mcp/blog-provider.js +27 -0
- package/dist/mcp/blog-provider.js.map +1 -0
- package/dist/mcp/blog-theme-authoring-prompt.d.ts +19 -0
- package/dist/mcp/blog-theme-authoring-prompt.d.ts.map +1 -0
- package/dist/mcp/blog-theme-authoring-prompt.js +171 -0
- package/dist/mcp/blog-theme-authoring-prompt.js.map +1 -0
- package/dist/mcp/category-tools.d.ts +45 -0
- package/dist/mcp/category-tools.d.ts.map +1 -0
- package/dist/mcp/category-tools.js +14 -0
- package/dist/mcp/category-tools.js.map +1 -0
- package/dist/mcp/comment-tools.d.ts +44 -0
- package/dist/mcp/comment-tools.d.ts.map +1 -0
- package/dist/mcp/comment-tools.js +15 -0
- package/dist/mcp/comment-tools.js.map +1 -0
- package/dist/mcp/friend-link-tools.d.ts +63 -0
- package/dist/mcp/friend-link-tools.d.ts.map +1 -0
- package/dist/mcp/friend-link-tools.js +16 -0
- package/dist/mcp/friend-link-tools.js.map +1 -0
- package/dist/mcp/page-tools.d.ts +67 -0
- package/dist/mcp/page-tools.d.ts.map +1 -0
- package/dist/mcp/page-tools.js +36 -0
- package/dist/mcp/page-tools.js.map +1 -0
- package/dist/mcp/post-tools.d.ts +114 -0
- package/dist/mcp/post-tools.d.ts.map +1 -0
- package/dist/mcp/post-tools.js +122 -0
- package/dist/mcp/post-tools.js.map +1 -0
- package/dist/mcp/tag-tools.d.ts +37 -0
- package/dist/mcp/tag-tools.d.ts.map +1 -0
- package/dist/mcp/tag-tools.js +14 -0
- package/dist/mcp/tag-tools.js.map +1 -0
- package/dist/mcp/theme-tools.d.ts +16 -0
- package/dist/mcp/theme-tools.d.ts.map +1 -0
- package/dist/mcp/theme-tools.js +71 -0
- package/dist/mcp/theme-tools.js.map +1 -0
- package/dist/mcp/tool-descriptions.d.ts +5 -0
- package/dist/mcp/tool-descriptions.d.ts.map +1 -0
- package/dist/mcp/tool-descriptions.js +51 -0
- package/dist/mcp/tool-descriptions.js.map +1 -0
- package/dist/mcp/tool-support.d.ts +242 -0
- package/dist/mcp/tool-support.d.ts.map +1 -0
- package/dist/mcp/tool-support.js +127 -0
- package/dist/mcp/tool-support.js.map +1 -0
- package/dist/messages/browser/dispatch.msg.d.ts +3 -0
- package/dist/messages/browser/dispatch.msg.d.ts.map +1 -0
- package/dist/messages/browser/dispatch.msg.js +9 -0
- package/dist/messages/browser/dispatch.msg.js.map +1 -0
- package/dist/messages/public/categories/list.msg.d.ts +3 -0
- package/dist/messages/public/categories/list.msg.d.ts.map +1 -0
- package/dist/messages/public/categories/list.msg.js +8 -0
- package/dist/messages/public/categories/list.msg.js.map +1 -0
- package/dist/messages/public/comments/list.msg.d.ts +3 -0
- package/dist/messages/public/comments/list.msg.d.ts.map +1 -0
- package/dist/messages/public/comments/list.msg.js +8 -0
- package/dist/messages/public/comments/list.msg.js.map +1 -0
- package/dist/messages/public/comments/recent.msg.d.ts +3 -0
- package/dist/messages/public/comments/recent.msg.d.ts.map +1 -0
- package/dist/messages/public/comments/recent.msg.js +8 -0
- package/dist/messages/public/comments/recent.msg.js.map +1 -0
- package/dist/messages/public/friend-links/list.msg.d.ts +3 -0
- package/dist/messages/public/friend-links/list.msg.d.ts.map +1 -0
- package/dist/messages/public/friend-links/list.msg.js +8 -0
- package/dist/messages/public/friend-links/list.msg.js.map +1 -0
- package/dist/messages/public/pages/list.msg.d.ts +3 -0
- package/dist/messages/public/pages/list.msg.d.ts.map +1 -0
- package/dist/messages/public/pages/list.msg.js +8 -0
- package/dist/messages/public/pages/list.msg.js.map +1 -0
- package/dist/messages/public/pages/read.msg.d.ts +3 -0
- package/dist/messages/public/pages/read.msg.d.ts.map +1 -0
- package/dist/messages/public/pages/read.msg.js +8 -0
- package/dist/messages/public/pages/read.msg.js.map +1 -0
- package/dist/messages/public/posts/archive.msg.d.ts +3 -0
- package/dist/messages/public/posts/archive.msg.d.ts.map +1 -0
- package/dist/messages/public/posts/archive.msg.js +8 -0
- package/dist/messages/public/posts/archive.msg.js.map +1 -0
- package/dist/messages/public/posts/connections.msg.d.ts +3 -0
- package/dist/messages/public/posts/connections.msg.d.ts.map +1 -0
- package/dist/messages/public/posts/connections.msg.js +8 -0
- package/dist/messages/public/posts/connections.msg.js.map +1 -0
- package/dist/messages/public/posts/list.msg.d.ts +3 -0
- package/dist/messages/public/posts/list.msg.d.ts.map +1 -0
- package/dist/messages/public/posts/list.msg.js +8 -0
- package/dist/messages/public/posts/list.msg.js.map +1 -0
- package/dist/messages/public/posts/open.msg.d.ts +3 -0
- package/dist/messages/public/posts/open.msg.d.ts.map +1 -0
- package/dist/messages/public/posts/open.msg.js +8 -0
- package/dist/messages/public/posts/open.msg.js.map +1 -0
- package/dist/messages/public/posts/read.msg.d.ts +3 -0
- package/dist/messages/public/posts/read.msg.d.ts.map +1 -0
- package/dist/messages/public/posts/read.msg.js +8 -0
- package/dist/messages/public/posts/read.msg.js.map +1 -0
- package/dist/messages/public/tags/list.msg.d.ts +3 -0
- package/dist/messages/public/tags/list.msg.d.ts.map +1 -0
- package/dist/messages/public/tags/list.msg.js +8 -0
- package/dist/messages/public/tags/list.msg.js.map +1 -0
- package/dist/migrations/index.d.ts +3 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +2 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/persistence/category-store.d.ts +23 -0
- package/dist/persistence/category-store.d.ts.map +1 -0
- package/dist/persistence/category-store.js +86 -0
- package/dist/persistence/category-store.js.map +1 -0
- package/dist/persistence/comment-store.d.ts +41 -0
- package/dist/persistence/comment-store.d.ts.map +1 -0
- package/dist/persistence/comment-store.js +146 -0
- package/dist/persistence/comment-store.js.map +1 -0
- package/dist/persistence/entities.d.ts +103 -0
- package/dist/persistence/entities.d.ts.map +1 -0
- package/dist/persistence/entities.js +188 -0
- package/dist/persistence/entities.js.map +1 -0
- package/dist/persistence/friend-link-store.d.ts +26 -0
- package/dist/persistence/friend-link-store.d.ts.map +1 -0
- package/dist/persistence/friend-link-store.js +80 -0
- package/dist/persistence/friend-link-store.js.map +1 -0
- package/dist/persistence/page-store.d.ts +35 -0
- package/dist/persistence/page-store.d.ts.map +1 -0
- package/dist/persistence/page-store.js +125 -0
- package/dist/persistence/page-store.js.map +1 -0
- package/dist/persistence/post-engagement-store.d.ts +23 -0
- package/dist/persistence/post-engagement-store.d.ts.map +1 -0
- package/dist/persistence/post-engagement-store.js +85 -0
- package/dist/persistence/post-engagement-store.js.map +1 -0
- package/dist/persistence/post-store.d.ts +87 -0
- package/dist/persistence/post-store.d.ts.map +1 -0
- package/dist/persistence/post-store.js +465 -0
- package/dist/persistence/post-store.js.map +1 -0
- package/dist/persistence/tag-store.d.ts +21 -0
- package/dist/persistence/tag-store.d.ts.map +1 -0
- package/dist/persistence/tag-store.js +82 -0
- package/dist/persistence/tag-store.js.map +1 -0
- package/dist/services/application.service.d.ts +4 -0
- package/dist/services/application.service.d.ts.map +1 -0
- package/dist/services/application.service.js +22 -0
- package/dist/services/application.service.js.map +1 -0
- package/dist/services/blog-runtime.service.d.ts +10 -0
- package/dist/services/blog-runtime.service.d.ts.map +1 -0
- package/dist/services/blog-runtime.service.js +32 -0
- package/dist/services/blog-runtime.service.js.map +1 -0
- package/dist/services/blog.boot.d.ts +6 -0
- package/dist/services/blog.boot.d.ts.map +1 -0
- package/dist/services/blog.boot.js +13 -0
- package/dist/services/blog.boot.js.map +1 -0
- package/dist/services/browser-api-provider.service.d.ts +4 -0
- package/dist/services/browser-api-provider.service.d.ts.map +1 -0
- package/dist/services/browser-api-provider.service.js +25 -0
- package/dist/services/browser-api-provider.service.js.map +1 -0
- package/dist/services/config.service.d.ts +3 -0
- package/dist/services/config.service.d.ts.map +1 -0
- package/dist/services/config.service.js +22 -0
- package/dist/services/config.service.js.map +1 -0
- package/dist/services/database.service.d.ts +3 -0
- package/dist/services/database.service.d.ts.map +1 -0
- package/dist/services/database.service.js +16 -0
- package/dist/services/database.service.js.map +1 -0
- package/dist/services/logger.service.d.ts +4 -0
- package/dist/services/logger.service.d.ts.map +1 -0
- package/dist/services/logger.service.js +8 -0
- package/dist/services/logger.service.js.map +1 -0
- package/dist/services/mcp-provider.service.d.ts +3 -0
- package/dist/services/mcp-provider.service.d.ts.map +1 -0
- package/dist/services/mcp-provider.service.js +17 -0
- package/dist/services/mcp-provider.service.js.map +1 -0
- package/dist/services/redis.service.d.ts +4 -0
- package/dist/services/redis.service.d.ts.map +1 -0
- package/dist/services/redis.service.js +18 -0
- package/dist/services/redis.service.js.map +1 -0
- package/dist/services/theme-control.service.d.ts +4 -0
- package/dist/services/theme-control.service.d.ts.map +1 -0
- package/dist/services/theme-control.service.js +53 -0
- package/dist/services/theme-control.service.js.map +1 -0
- package/dist/themes/theme-catalog.d.ts +40 -0
- package/dist/themes/theme-catalog.d.ts.map +1 -0
- package/dist/themes/theme-catalog.js +164 -0
- package/dist/themes/theme-catalog.js.map +1 -0
- package/dist/themes/theme-control.d.ts +16 -0
- package/dist/themes/theme-control.d.ts.map +1 -0
- package/dist/themes/theme-control.js +57 -0
- package/dist/themes/theme-control.js.map +1 -0
- package/dist/themes/theme-discovery-runtime.d.ts +41 -0
- package/dist/themes/theme-discovery-runtime.d.ts.map +1 -0
- package/dist/themes/theme-discovery-runtime.js +109 -0
- package/dist/themes/theme-discovery-runtime.js.map +1 -0
- package/dist/themes/theme-generation-store.d.ts +14 -0
- package/dist/themes/theme-generation-store.d.ts.map +1 -0
- package/dist/themes/theme-generation-store.js +49 -0
- package/dist/themes/theme-generation-store.js.map +1 -0
- package/dist/themes/theme-selection-publisher.d.ts +28 -0
- package/dist/themes/theme-selection-publisher.d.ts.map +1 -0
- package/dist/themes/theme-selection-publisher.js +92 -0
- package/dist/themes/theme-selection-publisher.js.map +1 -0
- package/dist/themes/theme-selection-store.d.ts +22 -0
- package/dist/themes/theme-selection-store.d.ts.map +1 -0
- package/dist/themes/theme-selection-store.js +84 -0
- package/dist/themes/theme-selection-store.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { blogThemeSelectionSchema, blogThemeSelectionTopic, } from '@zlooks.cn/blog-shared';
|
|
2
|
+
export class ThemeSelectionPublisher {
|
|
3
|
+
options;
|
|
4
|
+
#clock;
|
|
5
|
+
#publication;
|
|
6
|
+
#timer;
|
|
7
|
+
#refreshing;
|
|
8
|
+
#closing;
|
|
9
|
+
#closed = false;
|
|
10
|
+
#sequence = -1;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
if (!Number.isSafeInteger(options.leaseMs) || options.leaseMs < 500 || options.leaseMs > 30_000) {
|
|
14
|
+
throw new TypeError('Blog theme selection lease must be between 500 and 30000 milliseconds');
|
|
15
|
+
}
|
|
16
|
+
this.#clock = options.clock ?? (() => new Date());
|
|
17
|
+
}
|
|
18
|
+
async start() {
|
|
19
|
+
if (this.#closed)
|
|
20
|
+
throw new Error('Blog theme selection publisher is closed');
|
|
21
|
+
if (this.#publication)
|
|
22
|
+
return;
|
|
23
|
+
const selection = await this.#announcement();
|
|
24
|
+
this.#publication = await this.options.application.publish(blogThemeSelectionTopic(this.options.instanceId), selection);
|
|
25
|
+
this.#timer = setInterval(() => {
|
|
26
|
+
void this.refresh().catch((error) => this.options.onError?.(error));
|
|
27
|
+
}, Math.max(250, Math.floor(this.options.leaseMs / 2)));
|
|
28
|
+
this.#timer.unref();
|
|
29
|
+
}
|
|
30
|
+
refresh(requiredRevision = 0) {
|
|
31
|
+
if (this.#closed)
|
|
32
|
+
return Promise.reject(new Error('Blog theme selection publisher is closed'));
|
|
33
|
+
if (this.#refreshing) {
|
|
34
|
+
if (requiredRevision === 0)
|
|
35
|
+
return this.#refreshing;
|
|
36
|
+
const operation = this.#refreshing.then((current) => current.revision >= requiredRevision ? current : this.#refresh(), () => this.#refresh());
|
|
37
|
+
return this.#trackRefresh(operation);
|
|
38
|
+
}
|
|
39
|
+
return this.#beginRefresh();
|
|
40
|
+
}
|
|
41
|
+
#beginRefresh() {
|
|
42
|
+
return this.#trackRefresh(this.#refresh());
|
|
43
|
+
}
|
|
44
|
+
#trackRefresh(operation) {
|
|
45
|
+
this.#refreshing = operation;
|
|
46
|
+
void operation.finally(() => {
|
|
47
|
+
if (this.#refreshing === operation)
|
|
48
|
+
this.#refreshing = undefined;
|
|
49
|
+
}).catch(() => undefined);
|
|
50
|
+
return operation;
|
|
51
|
+
}
|
|
52
|
+
async #refresh() {
|
|
53
|
+
const selection = await this.#announcement();
|
|
54
|
+
const publication = this.#publication;
|
|
55
|
+
if (!publication)
|
|
56
|
+
throw new Error('Blog theme selection publisher is not started');
|
|
57
|
+
await publication.update(selection);
|
|
58
|
+
return selection;
|
|
59
|
+
}
|
|
60
|
+
async #announcement() {
|
|
61
|
+
const selection = await this.options.store.read();
|
|
62
|
+
const issuedAt = this.#clock();
|
|
63
|
+
this.#sequence = Math.max(this.#sequence + 1, issuedAt.getTime());
|
|
64
|
+
return blogThemeSelectionSchema.parse({
|
|
65
|
+
instanceId: this.options.instanceId,
|
|
66
|
+
...selection,
|
|
67
|
+
lease: {
|
|
68
|
+
issuedAt: issuedAt.toISOString(),
|
|
69
|
+
expiresAt: new Date(issuedAt.getTime() + this.options.leaseMs).toISOString(),
|
|
70
|
+
sequence: this.#sequence,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
close() {
|
|
75
|
+
if (this.#closing)
|
|
76
|
+
return this.#closing;
|
|
77
|
+
this.#closed = true;
|
|
78
|
+
const operation = this.#close();
|
|
79
|
+
this.#closing = operation;
|
|
80
|
+
return operation.finally(() => { if (this.#closing === operation)
|
|
81
|
+
this.#closing = undefined; });
|
|
82
|
+
}
|
|
83
|
+
async #close() {
|
|
84
|
+
if (this.#timer)
|
|
85
|
+
clearInterval(this.#timer);
|
|
86
|
+
this.#timer = undefined;
|
|
87
|
+
await this.#refreshing?.catch(() => undefined);
|
|
88
|
+
await this.#publication?.unpublish();
|
|
89
|
+
this.#publication = undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=theme-selection-publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-selection-publisher.js","sourceRoot":"","sources":["../../src/themes/theme-selection-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const selectionSchema: z.ZodObject<{
|
|
3
|
+
themeId: z.ZodReadonly<z.ZodString>;
|
|
4
|
+
revision: z.ZodReadonly<z.ZodNumber>;
|
|
5
|
+
updatedAt: z.ZodISODateTime;
|
|
6
|
+
updatedBy: z.ZodString;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type ThemeSelectionState = Readonly<z.infer<typeof selectionSchema>>;
|
|
9
|
+
export interface ThemeSelectionRedis {
|
|
10
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
11
|
+
eval(script: string, keyCount: number, ...args: readonly (string | number)[]): Promise<unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare class RedisThemeSelectionStore {
|
|
14
|
+
#private;
|
|
15
|
+
private readonly redis;
|
|
16
|
+
private readonly clock;
|
|
17
|
+
constructor(redis: ThemeSelectionRedis, clock?: () => Date);
|
|
18
|
+
read(): Promise<ThemeSelectionState>;
|
|
19
|
+
select(themeId: string, updatedBy: string, signal?: AbortSignal): Promise<ThemeSelectionState>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=theme-selection-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-selection-store.d.ts","sourceRoot":"","sources":["../../src/themes/theme-selection-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,eAAe;;;;;kBAKnB,CAAC;AAOH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjG;AA4BD,qBAAa,wBAAwB;;IAEjC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFxB,YACmB,KAAK,EAAE,mBAAmB,EAC1B,KAAK,GAAE,MAAM,IAAuB,EACnD;IAES,IAAI,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAEhD;IAqBY,MAAM,CACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAsB9B;CACF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { blogThemeIdSchema, blogThemeSelectionRevisionSchema } from '@zlooks.cn/blog-shared';
|
|
3
|
+
const REDIS_KEY = 'theme:selection';
|
|
4
|
+
const selectionSchema = z.strictObject({
|
|
5
|
+
themeId: blogThemeIdSchema,
|
|
6
|
+
revision: blogThemeSelectionRevisionSchema,
|
|
7
|
+
updatedAt: z.iso.datetime({ offset: true }),
|
|
8
|
+
updatedBy: z.string().trim().min(1).max(256),
|
|
9
|
+
});
|
|
10
|
+
const persistedSelectionSchema = selectionSchema.extend({
|
|
11
|
+
revision: z.string().regex(/^(?:0|[1-9][0-9]*)$/)
|
|
12
|
+
.transform(Number)
|
|
13
|
+
.pipe(blogThemeSelectionRevisionSchema),
|
|
14
|
+
});
|
|
15
|
+
const MAX_CAS_ATTEMPTS = 8;
|
|
16
|
+
const casResultSchema = z.tuple([z.enum(['ok', 'conflict'])]);
|
|
17
|
+
const CAS_SCRIPT = `
|
|
18
|
+
local count = redis.call('HLEN', KEYS[1])
|
|
19
|
+
if ARGV[1] == '1' then
|
|
20
|
+
if count ~= 0 then return {'conflict'} end
|
|
21
|
+
else
|
|
22
|
+
if count ~= 4 then return {'conflict'} end
|
|
23
|
+
local current = redis.call('HMGET', KEYS[1], 'themeId', 'revision', 'updatedAt', 'updatedBy')
|
|
24
|
+
if current[1] ~= ARGV[2] or current[2] ~= ARGV[3]
|
|
25
|
+
or current[3] ~= ARGV[4] or current[4] ~= ARGV[5] then
|
|
26
|
+
return {'conflict'}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
redis.call('HSET', KEYS[1],
|
|
30
|
+
'themeId', ARGV[6], 'revision', ARGV[7], 'updatedAt', ARGV[8], 'updatedBy', ARGV[9])
|
|
31
|
+
return {'ok'}
|
|
32
|
+
`;
|
|
33
|
+
export class RedisThemeSelectionStore {
|
|
34
|
+
redis;
|
|
35
|
+
clock;
|
|
36
|
+
constructor(redis, clock = () => new Date()) {
|
|
37
|
+
this.redis = redis;
|
|
38
|
+
this.clock = clock;
|
|
39
|
+
}
|
|
40
|
+
async read() {
|
|
41
|
+
return (await this.#readSnapshot()).state;
|
|
42
|
+
}
|
|
43
|
+
async #readSnapshot() {
|
|
44
|
+
const persisted = await this.redis.hgetall(REDIS_KEY);
|
|
45
|
+
if (Object.keys(persisted).length === 0) {
|
|
46
|
+
const raw = {
|
|
47
|
+
themeId: 'default', revision: '0', updatedAt: new Date(0).toISOString(), updatedBy: 'bootstrap',
|
|
48
|
+
};
|
|
49
|
+
return Object.freeze({ empty: true, raw: Object.freeze(raw), state: Object.freeze(selectionSchema.parse({
|
|
50
|
+
themeId: 'default', revision: 0, updatedAt: new Date(0).toISOString(), updatedBy: 'bootstrap',
|
|
51
|
+
})) });
|
|
52
|
+
}
|
|
53
|
+
const parsed = persistedSelectionSchema.safeParse(persisted);
|
|
54
|
+
if (!parsed.success)
|
|
55
|
+
throw new Error('Blog theme selection in Redis is invalid', { cause: parsed.error });
|
|
56
|
+
const raw = {
|
|
57
|
+
themeId: persisted.themeId, revision: persisted.revision,
|
|
58
|
+
updatedAt: persisted.updatedAt, updatedBy: persisted.updatedBy,
|
|
59
|
+
};
|
|
60
|
+
return Object.freeze({ empty: false, raw: Object.freeze(raw), state: Object.freeze(parsed.data) });
|
|
61
|
+
}
|
|
62
|
+
async select(themeId, updatedBy, signal) {
|
|
63
|
+
const selectedThemeId = blogThemeIdSchema.parse(themeId);
|
|
64
|
+
const actor = z.string().trim().min(1).max(256).parse(updatedBy);
|
|
65
|
+
const updatedAt = this.clock().toISOString();
|
|
66
|
+
for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt += 1) {
|
|
67
|
+
const current = await this.#readSnapshot();
|
|
68
|
+
signal?.throwIfAborted();
|
|
69
|
+
if (current.state.themeId === selectedThemeId)
|
|
70
|
+
return current.state;
|
|
71
|
+
if (current.state.revision >= Number.MAX_SAFE_INTEGER - 1) {
|
|
72
|
+
throw new Error('Blog theme selection revision is exhausted');
|
|
73
|
+
}
|
|
74
|
+
const next = Object.freeze(selectionSchema.parse({
|
|
75
|
+
themeId: selectedThemeId, revision: current.state.revision + 1, updatedAt, updatedBy: actor,
|
|
76
|
+
}));
|
|
77
|
+
const [result] = casResultSchema.parse(await this.redis.eval(CAS_SCRIPT, 1, REDIS_KEY, current.empty ? '1' : '0', current.raw.themeId, current.raw.revision, current.raw.updatedAt, current.raw.updatedBy, next.themeId, String(next.revision), next.updatedAt, next.updatedBy));
|
|
78
|
+
if (result === 'ok')
|
|
79
|
+
return next;
|
|
80
|
+
}
|
|
81
|
+
throw new Error('Blog theme selection changed concurrently; retry the operation');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=theme-selection-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-selection-store.js","sourceRoot":"","sources":["../../src/themes/theme-selection-store.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zlooks.cn/blog-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24.0.0"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"zlooks-blog-server": "dist/command/index.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"zlooks": {
|
|
16
|
+
"kind": "service",
|
|
17
|
+
"description": "博客领域服务",
|
|
18
|
+
"dependsOn": [],
|
|
19
|
+
"commands": {
|
|
20
|
+
"db": [
|
|
21
|
+
"sync",
|
|
22
|
+
"migrate"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "pnpm run clean && tsc -p tsconfig.json && fix-esm-import-path --preserve-import-type ./dist",
|
|
28
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
29
|
+
"dev": "hile start --dev --env-file ~/.zlooks.cn/.env",
|
|
30
|
+
"start": "hile start --env-file ~/.zlooks.cn/.env",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@hile/context": "4.0.2",
|
|
36
|
+
"@hile/core": "4.0.1",
|
|
37
|
+
"@hile/ioredis": "4.0.1",
|
|
38
|
+
"@hile/logger": "4.0.1",
|
|
39
|
+
"@hile/mcp": "1.0.4",
|
|
40
|
+
"@hile/message-loader": "4.0.3",
|
|
41
|
+
"@hile/micro": "4.0.3",
|
|
42
|
+
"@hile/typeorm": "4.0.1",
|
|
43
|
+
"@zlooks.cn/blog-schema": "1.0.0",
|
|
44
|
+
"@zlooks.cn/blog-shared": "1.0.0",
|
|
45
|
+
"@zlooks.cn/browser-api": "1.0.0",
|
|
46
|
+
"@zlooks.cn/database-command": "1.0.0",
|
|
47
|
+
"@zlooks.cn/infrastructure": "1.0.0",
|
|
48
|
+
"@zlooks.cn/public-host-contract": "1.0.0",
|
|
49
|
+
"@zlooks.cn/registry-config": "1.0.0",
|
|
50
|
+
"@zlooks.cn/service-command": "1.0.0",
|
|
51
|
+
"@zlooks.cn/user-shared": "1.0.0",
|
|
52
|
+
"@zlooks.cn/utils": "1.0.0",
|
|
53
|
+
"detect-port": "2.1.0",
|
|
54
|
+
"ioredis": "5.11.1",
|
|
55
|
+
"ip2region-ts": "2.0.1",
|
|
56
|
+
"mdast-util-to-string": "4.0.0",
|
|
57
|
+
"pg": "8.23.0",
|
|
58
|
+
"remark-parse": "11.0.0",
|
|
59
|
+
"typeorm": "1.1.0",
|
|
60
|
+
"unified": "11.0.5",
|
|
61
|
+
"unist-util-visit": "5.1.0",
|
|
62
|
+
"zod": "4.4.3"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@hile/cli": "4.0.4",
|
|
66
|
+
"@types/mdast": "4.0.4",
|
|
67
|
+
"@types/node": "26.2.0",
|
|
68
|
+
"fix-esm-import-path": "1.10.3",
|
|
69
|
+
"pg-mem": "3.0.14",
|
|
70
|
+
"typescript": "7.0.2",
|
|
71
|
+
"vitest": "4.1.11"
|
|
72
|
+
},
|
|
73
|
+
"gitHead": "a3e825c2a62561f73f49a54720e286f08da63429"
|
|
74
|
+
}
|