memi-board 0.42.1 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -196,10 +196,26 @@ const { post: postSeo } = await useMemiBoardPostSeo({
196
196
  `/board/${encodeURIComponent(categoryId.value)}/${encodeURIComponent(id.value)}`,
197
197
  ),
198
198
  })
199
- // postSeo: id · title · previewImage 등 — 상세 로드와 공유 가능
199
+ // postSeo: id · title · previewImage 등 — SSR 첫 로드에서는 바로 채워진다.
200
+ // 클라이언트 이동에서는 화면 전환을 막지 않으려고 기다리지 않으므로 처음엔 null 일 수 있다.
201
+
202
+ const { resolvePostIdBySlug } = useMemiBoardPosts(categoryId)
203
+ const internalId = ref('')
204
+ watch([categoryId, id], async ([category, slug]) => {
205
+ if (postSeo.value?.id && postSeo.value.category === category && postSeo.value.slug === slug) {
206
+ internalId.value = postSeo.value.id
207
+ return
208
+ }
209
+ if (import.meta.server) return
210
+ // id 만 조회 (본문은 MemiBoardDetail 이 구독). 방금 작성한 글은 조회 없이 바로 나온다.
211
+ const result = await resolvePostIdBySlug(slug)
212
+ internalId.value = result.status === 'ok' ? result.id : ''
213
+ }, { immediate: true })
200
214
  </script>
201
215
  ```
202
216
 
217
+ > 상세·수정 페이지에서 slug → id 는 `getPostBySlug`(본문까지 읽음) 대신 `resolvePostIdBySlug` 를 쓴다. 저장 직후 미리보기 진입이 Firestore 왕복 2회만큼 빨라진다.
218
+
203
219
  | composable | 대상 | OG 요약 |
204
220
  |------------|------|---------|
205
221
  | `useMemiBoardListSeo` | 목록 | 카테고리 label·description, 최근 공개 글 이미지 |
@@ -45,6 +45,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
45
45
  readonly nanoseconds: number;
46
46
  toDate: () => Date;
47
47
  toMillis: () => number;
48
+ toInstant: () => Temporal.Instant;
48
49
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
49
50
  toString: () => string;
50
51
  toJSON: () => {
@@ -59,6 +60,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
59
60
  readonly nanoseconds: number;
60
61
  toDate: () => Date;
61
62
  toMillis: () => number;
63
+ toInstant: () => Temporal.Instant;
62
64
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
63
65
  toString: () => string;
64
66
  toJSON: () => {
@@ -74,6 +76,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
74
76
  readonly nanoseconds: number;
75
77
  toDate: () => Date;
76
78
  toMillis: () => number;
79
+ toInstant: () => Temporal.Instant;
77
80
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
78
81
  toString: () => string;
79
82
  toJSON: () => {
@@ -107,6 +110,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
107
110
  readonly nanoseconds: number;
108
111
  toDate: () => Date;
109
112
  toMillis: () => number;
113
+ toInstant: () => Temporal.Instant;
110
114
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
111
115
  toString: () => string;
112
116
  toJSON: () => {
@@ -121,6 +125,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
121
125
  readonly nanoseconds: number;
122
126
  toDate: () => Date;
123
127
  toMillis: () => number;
128
+ toInstant: () => Temporal.Instant;
124
129
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
125
130
  toString: () => string;
126
131
  toJSON: () => {
@@ -136,6 +141,7 @@ export declare function useMemiBoardReplies(boardId: string, postId: string, roo
136
141
  readonly nanoseconds: number;
137
142
  toDate: () => Date;
138
143
  toMillis: () => number;
144
+ toInstant: () => Temporal.Instant;
139
145
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
140
146
  toString: () => string;
141
147
  toJSON: () => {
@@ -11,6 +11,8 @@ export interface CreatePostInput {
11
11
  authorName: string | null;
12
12
  authorPhoto: string | null;
13
13
  moderationModel?: string;
14
+ /** resolveUniqueSlug 로 미리 구한 slug. 없으면 createPost 가 직접 구한다. */
15
+ slug?: string;
14
16
  }
15
17
  export interface UpdatePostInput {
16
18
  title: string;
@@ -29,6 +31,17 @@ export type GetPostBySlugResult = {
29
31
  status: 'error';
30
32
  message: string;
31
33
  };
34
+ export type ResolvePostIdResult = {
35
+ status: 'ok';
36
+ id: string;
37
+ } | {
38
+ status: 'not-found';
39
+ } | {
40
+ status: 'permission-denied';
41
+ } | {
42
+ status: 'error';
43
+ message: string;
44
+ };
32
45
  export declare function isFirestorePermissionDenied(error: unknown): boolean;
33
46
  /** 목록은 posts 메타만, 본문(body/main)은 상세에서만. */
34
47
  export declare function useMemiBoardPosts(boardId: MaybeRefOrGetter<string>): {
@@ -44,6 +57,8 @@ export declare function useMemiBoardPosts(boardId: MaybeRefOrGetter<string>): {
44
57
  }>;
45
58
  getPost: (id: string) => Promise<PostDetail | null>;
46
59
  getPostBySlug: (slug: string) => Promise<GetPostBySlugResult>;
60
+ resolvePostIdBySlug: (slug: string) => Promise<ResolvePostIdResult>;
61
+ resolveUniqueSlug: (title: string) => Promise<string>;
47
62
  getAdjacentPosts: (current: PostModel) => Promise<{
48
63
  previous: PostModel | null;
49
64
  next: PostModel | null;
@@ -35,6 +35,7 @@ export declare function useMemiBoardReportQueue(options?: {
35
35
  readonly nanoseconds: number;
36
36
  toDate: () => Date;
37
37
  toMillis: () => number;
38
+ toInstant: () => Temporal.Instant;
38
39
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
39
40
  toString: () => string;
40
41
  toJSON: () => {
@@ -52,6 +53,7 @@ export declare function useMemiBoardReportQueue(options?: {
52
53
  readonly nanoseconds: number;
53
54
  toDate: () => Date;
54
55
  toMillis: () => number;
56
+ toInstant: () => Temporal.Instant;
55
57
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
56
58
  toString: () => string;
57
59
  toJSON: () => {
@@ -76,6 +78,7 @@ export declare function useMemiBoardReportQueue(options?: {
76
78
  readonly nanoseconds: number;
77
79
  toDate: () => Date;
78
80
  toMillis: () => number;
81
+ toInstant: () => Temporal.Instant;
79
82
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
80
83
  toString: () => string;
81
84
  toJSON: () => {
@@ -93,6 +96,7 @@ export declare function useMemiBoardReportQueue(options?: {
93
96
  readonly nanoseconds: number;
94
97
  toDate: () => Date;
95
98
  toMillis: () => number;
99
+ toInstant: () => Temporal.Instant;
96
100
  isEqual: (other: import('firebase/firestore').Timestamp) => boolean;
97
101
  toString: () => string;
98
102
  toJSON: () => {
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export { boardPostOgTitle, boardPostOgDescription, boardListOgTitle, boardListOg
9
9
  export type { BoardPostSeoPayload, BoardListSeoPayload } from './utils/boardSeo';
10
10
  export { useMemiBoardAuth } from './composables/useMemiBoardAuth';
11
11
  export { useMemiBoardPosts, useMemiBoardPostList, useMemiBoardPost } from './composables/useMemiBoardPosts';
12
- export type { CreatePostInput, UpdatePostInput, GetPostBySlugResult } from './composables/useMemiBoardPosts';
12
+ export type { CreatePostInput, UpdatePostInput, GetPostBySlugResult, ResolvePostIdResult } from './composables/useMemiBoardPosts';
13
13
  export { isFirestorePermissionDenied } from './composables/useMemiBoardPosts';
14
14
  export { useMemiBoardUserPosts } from './composables/useMemiBoardUserPosts';
15
15
  export { useMemiBoardUserComments } from './composables/useMemiBoardUserComments';