@xrift/world-components 0.25.0 → 0.26.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.
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { buildLogEntryId, createLogEntry, defaultFormatTimestamp, mergeLogs, } from '../utils';
2
+ import { buildLogEntryId, createLogEntry, defaultFormatTimestamp, enrichLogsWithCache, isWriterAmong, mergeLogs, } from '../utils';
3
3
  describe('defaultFormatTimestamp', () => {
4
4
  it('HH:MM 形式でフォーマットする', () => {
5
5
  const date = new Date(2024, 0, 1, 9, 5);
@@ -115,6 +115,72 @@ describe('createLogEntry', () => {
115
115
  expect(entry.id).toBe('join-user-1-1');
116
116
  });
117
117
  });
118
+ describe('isWriterAmong', () => {
119
+ it('辞書順最小のIDがtargetIdと一致する場合はtrueを返す', () => {
120
+ expect(isWriterAmong(['user-b', 'user-a', 'user-c'], 'user-a')).toBe(true);
121
+ });
122
+ it('辞書順最小のIDがtargetIdと一致しない場合はfalseを返す', () => {
123
+ expect(isWriterAmong(['user-b', 'user-a', 'user-c'], 'user-b')).toBe(false);
124
+ });
125
+ it('targetIdがundefinedの場合はfalseを返す', () => {
126
+ expect(isWriterAmong(['user-a', 'user-b'], undefined)).toBe(false);
127
+ });
128
+ it('候補が空配列の場合はfalseを返す', () => {
129
+ expect(isWriterAmong([], 'user-a')).toBe(false);
130
+ });
131
+ it('候補にundefinedが含まれていてもフィルタして判定する', () => {
132
+ expect(isWriterAmong([undefined, 'user-b', 'user-a'], 'user-a')).toBe(true);
133
+ });
134
+ it('候補が1つだけでtargetIdと一致する場合はtrueを返す', () => {
135
+ expect(isWriterAmong(['user-a'], 'user-a')).toBe(true);
136
+ });
137
+ });
138
+ describe('enrichLogsWithCache', () => {
139
+ const unknownEntry = {
140
+ id: 'join-user-1-0',
141
+ type: 'join',
142
+ userId: 'user-1',
143
+ displayName: 'Unknown',
144
+ avatarUrl: null,
145
+ timestamp: '10:00',
146
+ };
147
+ const knownEntry = {
148
+ id: 'join-user-2-0',
149
+ type: 'join',
150
+ userId: 'user-2',
151
+ displayName: 'Bob',
152
+ avatarUrl: 'https://example.com/bob.png',
153
+ timestamp: '10:01',
154
+ };
155
+ it('Unknown エントリをキャッシュの情報で補完する', () => {
156
+ const cache = new Map([
157
+ ['user-1', { displayName: 'Alice', avatarUrl: 'https://example.com/alice.png' }],
158
+ ]);
159
+ const result = enrichLogsWithCache([unknownEntry], 'Unknown', cache);
160
+ expect(result[0].displayName).toBe('Alice');
161
+ expect(result[0].avatarUrl).toBe('https://example.com/alice.png');
162
+ });
163
+ it('Unknown でないエントリはそのまま返す', () => {
164
+ const logs = [knownEntry];
165
+ const cache = new Map([
166
+ ['user-2', { displayName: 'Bob2', avatarUrl: null }],
167
+ ]);
168
+ const result = enrichLogsWithCache(logs, 'Unknown', cache);
169
+ expect(result).toBe(logs);
170
+ });
171
+ it('キャッシュにないユーザーの Unknown はそのまま', () => {
172
+ const logs = [unknownEntry];
173
+ const cache = new Map();
174
+ const result = enrichLogsWithCache(logs, 'Unknown', cache);
175
+ expect(result).toBe(logs);
176
+ });
177
+ it('変更がなければ元の配列参照を返す', () => {
178
+ const logs = [knownEntry];
179
+ const cache = new Map();
180
+ const result = enrichLogsWithCache(logs, 'Unknown', cache);
181
+ expect(result).toBe(logs);
182
+ });
183
+ });
118
184
  describe('mergeLogs', () => {
119
185
  const baseEntry = {
120
186
  id: 'join-user-1-0',
@@ -1 +1 @@
1
- {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/__tests__/utils.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/__tests__/utils.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type Colors, type Labels, type LogEntry } from './types';
2
2
  export declare const DEFAULT_STATE_NAMESPACE = "entry-log";
3
- export declare const DEFAULT_MAX_ENTRIES = 20;
3
+ export declare const DEFAULT_MAX_ENTRIES = 10;
4
4
  export declare const DEFAULT_DISPLAY_NAME_FALLBACK = "Unknown";
5
5
  export declare const DEFAULT_LABELS: Labels;
6
6
  export declare const DEFAULT_COLORS: Colors;
@@ -1,5 +1,5 @@
1
1
  export const DEFAULT_STATE_NAMESPACE = 'entry-log';
2
- export const DEFAULT_MAX_ENTRIES = 20;
2
+ export const DEFAULT_MAX_ENTRIES = 10;
3
3
  export const DEFAULT_DISPLAY_NAME_FALLBACK = 'Unknown';
4
4
  export const DEFAULT_LABELS = {
5
5
  join: '入室',
@@ -1 +1 @@
1
- {"version":3,"file":"useEntryLog.d.ts","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/hooks/useEntryLog.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,QAAQ,EAGd,MAAM,UAAU,CAAA;AAGjB,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IACvC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;CACpC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,QAAQ,EAAE,CAmEnE"}
1
+ {"version":3,"file":"useEntryLog.d.ts","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/hooks/useEntryLog.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,QAAQ,EAGd,MAAM,UAAU,CAAA;AAGjB,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IACvC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;CACpC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,QAAQ,EAAE,CA8InE"}
@@ -1,9 +1,9 @@
1
- import { useEffect, useRef } from 'react';
1
+ import { useEffect, useMemo, useRef } from 'react';
2
2
  import { useUsers } from '../../../contexts/UsersContext';
3
3
  import { useInstanceState } from '../../../hooks/useInstanceState';
4
4
  import { useWorldEvent } from '../../../hooks/useWorldEvent';
5
5
  import { DEFAULT_LOGS } from '../constants';
6
- import { createLogEntry, mergeLogs } from '../utils';
6
+ import { createLogEntry, enrichLogsWithCache, isWriterAmong, mergeLogs } from '../utils';
7
7
  export function useEntryLog(options) {
8
8
  const { localUser, remoteUsers } = useUsers();
9
9
  const [logs, setLogs] = useInstanceState(`${options.stateNamespace}-logs`, DEFAULT_LOGS);
@@ -14,23 +14,51 @@ export function useEntryLog(options) {
14
14
  const optionsRef = useRef(options);
15
15
  optionsRef.current = options;
16
16
  // ユーザー情報キャッシュ(退室時に useUsers から消えている可能性があるため)
17
+ // レンダー本体で同期的に更新し、イベントコールバックより先にキャッシュを確定させる
17
18
  const userCacheRef = useRef(new Map());
19
+ if (localUser) {
20
+ userCacheRef.current.set(localUser.id, {
21
+ displayName: localUser.displayName,
22
+ avatarUrl: localUser.avatarUrl,
23
+ });
24
+ }
25
+ for (const user of remoteUsers) {
26
+ userCacheRef.current.set(user.id, {
27
+ displayName: user.displayName,
28
+ avatarUrl: user.avatarUrl,
29
+ });
30
+ }
31
+ // 自分自身の入室ログ補完(最初のユーザーのみ)
32
+ // 他のユーザーがいる場合はライターが user-joined イベントで書いてくれるため、
33
+ // ここでは自分しかいない(=最初のユーザー)場合のみ自分の入室ログを追加する。
34
+ // 自分で書くと未同期のローカル状態で上書きしてしまうため。
35
+ const selfJoinedRef = useRef(false);
18
36
  useEffect(() => {
19
- if (localUser) {
20
- userCacheRef.current.set(localUser.id, {
21
- displayName: localUser.displayName,
22
- avatarUrl: localUser.avatarUrl,
23
- });
24
- }
25
- for (const user of remoteUsers) {
26
- userCacheRef.current.set(user.id, {
27
- displayName: user.displayName,
28
- avatarUrl: user.avatarUrl,
29
- });
30
- }
31
- }, [localUser, remoteUsers]);
37
+ if (!localUser || selfJoinedRef.current)
38
+ return;
39
+ selfJoinedRef.current = true;
40
+ const alreadyJoined = logsRef.current.some((log) => log.type === 'join' && log.userId === localUser.id);
41
+ if (alreadyJoined)
42
+ return;
43
+ // 他のユーザーがいる場合、ライターが user-joined で書くので自分では書かない
44
+ if (remoteUsers.length > 0)
45
+ return;
46
+ const opts = optionsRef.current;
47
+ const entry = createLogEntry('join', localUser.id, localUser.displayName, localUser.avatarUrl, logsRef.current, opts.formatTimestamp);
48
+ setLogs((prev) => mergeLogs(prev, entry, opts.maxEntries));
49
+ opts.onJoin?.(entry);
50
+ }, [localUser, setLogs]);
32
51
  // user-joined イベント
52
+ // 入室者を除いた既存ユーザーの中で辞書順最小のクライアントだけが書き込む
33
53
  useWorldEvent('user-joined', (data) => {
54
+ if (!localUser)
55
+ return;
56
+ const existingIds = [
57
+ localUser.id,
58
+ ...remoteUsers.filter((u) => u.id !== data.userId).map((u) => u.id),
59
+ ];
60
+ if (!isWriterAmong(existingIds, localUser.id))
61
+ return;
34
62
  const opts = optionsRef.current;
35
63
  const cached = userCacheRef.current.get(data.userId);
36
64
  const entry = createLogEntry('join', data.userId, cached?.displayName ?? opts.displayNameFallback, cached?.avatarUrl ?? null, logsRef.current, opts.formatTimestamp);
@@ -38,13 +66,43 @@ export function useEntryLog(options) {
38
66
  opts.onJoin?.(entry);
39
67
  });
40
68
  // user-left イベント
69
+ // 退室者を除いた残存ユーザーの中で辞書順最小のクライアントだけが書き込む
41
70
  useWorldEvent('user-left', (data) => {
71
+ if (!localUser)
72
+ return;
73
+ const remainingIds = [
74
+ localUser.id,
75
+ ...remoteUsers.filter((u) => u.id !== data.userId).map((u) => u.id),
76
+ ];
77
+ if (!isWriterAmong(remainingIds, localUser.id))
78
+ return;
42
79
  const opts = optionsRef.current;
43
80
  const cached = userCacheRef.current.get(data.userId);
44
81
  const entry = createLogEntry('leave', data.userId, cached?.displayName ?? opts.displayNameFallback, cached?.avatarUrl ?? null, logsRef.current, opts.formatTimestamp);
45
82
  setLogs((prev) => mergeLogs(prev, entry, opts.maxEntries));
46
83
  opts.onLeave?.(entry);
47
84
  });
48
- return logs;
85
+ // Unknown ログの永続修復(ライターのみ)
86
+ // user-joined 発火時に remoteUsers 未更新でキャッシュミスした Unknown エントリを、
87
+ // 次のレンダーでキャッシュが更新された後に修正する
88
+ useEffect(() => {
89
+ if (!localUser)
90
+ return;
91
+ const fallback = optionsRef.current.displayNameFallback;
92
+ const currentLogs = logsRef.current;
93
+ if (!currentLogs.some((log) => log.displayName === fallback))
94
+ return;
95
+ const allIds = [localUser.id, ...remoteUsers.map((u) => u.id)];
96
+ if (!isWriterAmong(allIds, localUser.id))
97
+ return;
98
+ const fixedLogs = enrichLogsWithCache(currentLogs, fallback, userCacheRef.current);
99
+ if (fixedLogs !== currentLogs) {
100
+ setLogs(fixedLogs);
101
+ }
102
+ }, [localUser, remoteUsers, setLogs]);
103
+ // Unknown ログをキャッシュで補完して返す(表示の即時修正)
104
+ // 永続修復が走る前でも表示上は正しい名前を出す
105
+ const cacheSize = userCacheRef.current.size;
106
+ return useMemo(() => enrichLogsWithCache(logs, options.displayNameFallback, userCacheRef.current), [logs, options.displayNameFallback, cacheSize]);
49
107
  }
50
108
  //# sourceMappingURL=useEntryLog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEntryLog.js","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/hooks/useEntryLog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useEntryLog.js","sourceRoot":"","sources":["../../../../src/components/EntryLogBoard/hooks/useEntryLog.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,24 @@ export declare const buildLogEntryId: (type: LogType, userId: string, existingLo
19
19
  * ログエントリを生成する
20
20
  */
21
21
  export declare const createLogEntry: (type: LogType, userId: string, displayName: string, avatarUrl: string | null, existingLogs: LogEntry[], formatTimestamp: (date: Date) => string) => LogEntry;
22
+ /**
23
+ * 候補ID群の中で辞書順最小のIDがtargetIdと一致するかを判定する
24
+ *
25
+ * 暗黙的ライター選出に使用。全クライアントが同じ候補群を持つため、
26
+ * 辞書順最小のクライアントだけが書き込みを行う。
27
+ */
28
+ export declare const isWriterAmong: (candidateIds: (string | undefined)[], targetId: string | undefined) => boolean;
29
+ /**
30
+ * ログ内の Unknown 表示名をキャッシュで補完する
31
+ *
32
+ * user-joined イベント発火時にまだ remoteUsers が更新されておらず
33
+ * キャッシュミスで Unknown になったエントリを、後から修復する。
34
+ * 変更がなければ元の配列をそのまま返す(参照同一性を維持)。
35
+ */
36
+ export declare const enrichLogsWithCache: (logs: LogEntry[], fallbackName: string, cache: Map<string, {
37
+ displayName: string;
38
+ avatarUrl: string | null;
39
+ }>) => LogEntry[];
22
40
  /**
23
41
  * 既存ログに新しいエントリをマージする(重複排除・件数制限)
24
42
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/EntryLogBoard/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAErD;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM,IAAI,KAAG,MAInD,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,OAAO,EACb,QAAQ,MAAM,EACd,cAAc,QAAQ,EAAE,KACvB,MAKF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,OAAO,EACb,QAAQ,MAAM,EACd,aAAa,MAAM,EACnB,WAAW,MAAM,GAAG,IAAI,EACxB,cAAc,QAAQ,EAAE,EACxB,iBAAiB,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,KACtC,QAOD,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,GACpB,cAAc,QAAQ,EAAE,EACxB,UAAU,QAAQ,EAClB,YAAY,MAAM,KACjB,QAAQ,EAGV,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/EntryLogBoard/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAErD;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM,IAAI,KAAG,MAInD,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,OAAO,EACb,QAAQ,MAAM,EACd,cAAc,QAAQ,EAAE,KACvB,MAKF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,OAAO,EACb,QAAQ,MAAM,EACd,aAAa,MAAM,EACnB,WAAW,MAAM,GAAG,IAAI,EACxB,cAAc,QAAQ,EAAE,EACxB,iBAAiB,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,KACtC,QAOD,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,cAAc,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EACpC,UAAU,MAAM,GAAG,SAAS,KAC3B,OAIF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,QAAQ,EAAE,EAChB,cAAc,MAAM,EACpB,OAAO,GAAG,CAAC,MAAM,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,KACpE,QAAQ,EAeV,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GACpB,cAAc,QAAQ,EAAE,EACxB,UAAU,QAAQ,EAClB,YAAY,MAAM,KACjB,QAAQ,EAGV,CAAA"}
@@ -32,6 +32,44 @@ export const createLogEntry = (type, userId, displayName, avatarUrl, existingLog
32
32
  avatarUrl,
33
33
  timestamp: formatTimestamp(new Date()),
34
34
  });
35
+ /**
36
+ * 候補ID群の中で辞書順最小のIDがtargetIdと一致するかを判定する
37
+ *
38
+ * 暗黙的ライター選出に使用。全クライアントが同じ候補群を持つため、
39
+ * 辞書順最小のクライアントだけが書き込みを行う。
40
+ */
41
+ export const isWriterAmong = (candidateIds, targetId) => {
42
+ if (!targetId)
43
+ return false;
44
+ const sorted = candidateIds.filter((id) => id != null).sort();
45
+ return sorted.length > 0 && sorted[0] === targetId;
46
+ };
47
+ /**
48
+ * ログ内の Unknown 表示名をキャッシュで補完する
49
+ *
50
+ * user-joined イベント発火時にまだ remoteUsers が更新されておらず
51
+ * キャッシュミスで Unknown になったエントリを、後から修復する。
52
+ * 変更がなければ元の配列をそのまま返す(参照同一性を維持)。
53
+ */
54
+ export const enrichLogsWithCache = (logs, fallbackName, cache) => {
55
+ let needsEnrich = false;
56
+ for (const log of logs) {
57
+ if (log.displayName === fallbackName && cache.has(log.userId)) {
58
+ needsEnrich = true;
59
+ break;
60
+ }
61
+ }
62
+ if (!needsEnrich)
63
+ return logs;
64
+ return logs.map((log) => {
65
+ if (log.displayName !== fallbackName)
66
+ return log;
67
+ const cached = cache.get(log.userId);
68
+ if (!cached)
69
+ return log;
70
+ return { ...log, displayName: cached.displayName, avatarUrl: cached.avatarUrl };
71
+ });
72
+ };
35
73
  /**
36
74
  * 既存ログに新しいエントリをマージする(重複排除・件数制限)
37
75
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/components/EntryLogBoard/utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,IAAU,EAAU,EAAE;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC7D,OAAO,GAAG,KAAK,IAAI,OAAO,EAAE,CAAA;AAC9B,CAAC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,IAAa,EACb,MAAc,EACd,YAAwB,EAChB,EAAE;IACV,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CACvC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CACpD,CAAC,MAAM,CAAA;IACR,OAAO,GAAG,IAAI,IAAI,MAAM,IAAI,aAAa,EAAE,CAAA;AAC7C,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAa,EACb,MAAc,EACd,WAAmB,EACnB,SAAwB,EACxB,YAAwB,EACxB,eAAuC,EAC7B,EAAE,CAAC,CAAC;IACd,EAAE,EAAE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC;IAC/C,IAAI;IACJ,MAAM;IACN,WAAW;IACX,SAAS;IACT,SAAS,EAAE,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC;CACvC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,YAAwB,EACxB,QAAkB,EAClB,UAAkB,EACN,EAAE;IACd,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,YAAY,CAAA;IAC3E,OAAO,CAAC,GAAG,YAAY,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAA;AACvD,CAAC,CAAA"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/components/EntryLogBoard/utils.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ import { DoubleSide, Vector3 } from "three";
19
19
  import { useInstanceState } from "../../../../hooks/useInstanceState";
20
20
  import { TagChip } from "../TagChip";
21
21
  import { calculateLayout, getSelectedTags, groupTagsByColumn, } from "./utils";
22
- const HEAD_OFFSET_Y = 1.6;
22
+ const HEAD_OFFSET_Y = 2.6;
23
23
  export const TagDisplay = ({ userId, getMovement, tags, visible, instanceStateKey, }) => {
24
24
  const groupRef = useRef(null);
25
25
  const stateKey = `tag-${instanceStateKey}-${userId}`;
@@ -0,0 +1,34 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface TeleportDestination {
3
+ position: [number, number, number];
4
+ /** 度数法(0-360)省略時は現在の向きを維持 */
5
+ yaw?: number;
6
+ }
7
+ export interface TeleportContextValue {
8
+ teleport: (destination: TeleportDestination) => void;
9
+ }
10
+ /**
11
+ * 開発環境用のデフォルト実装(console.log のみ)
12
+ * プラットフォーム側が実装を注入しない場合に使用される
13
+ */
14
+ export declare const createDefaultTeleportImplementation: () => TeleportContextValue;
15
+ /**
16
+ * テレポート機能を提供する Context
17
+ * xrift-frontend 側で実装を注入し、ワールド側で利用できる
18
+ */
19
+ export declare const TeleportContext: import("react").Context<TeleportContextValue | null>;
20
+ interface Props {
21
+ value: TeleportContextValue;
22
+ children: ReactNode;
23
+ }
24
+ /**
25
+ * テレポート機能を提供する ContextProvider
26
+ */
27
+ export declare const TeleportProvider: ({ value, children }: Props) => import("react/jsx-runtime").JSX.Element;
28
+ /**
29
+ * テレポートの Context を取得する hook
30
+ * @throws {Error} TeleportProvider の外で呼び出された場合
31
+ */
32
+ export declare const useTeleportContext: () => TeleportContextValue;
33
+ export {};
34
+ //# sourceMappingURL=TeleportContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeleportContext.d.ts","sourceRoot":"","sources":["../../src/contexts/TeleportContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAA;AAEjE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAA;CACrD;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,QAAO,oBAGrD,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,sDAAmD,CAAA;AAE/E,UAAU,KAAK;IACb,KAAK,EAAE,oBAAoB,CAAA;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,qBAAqB,KAAK,4CAE1D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAMrC,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from 'react';
3
+ /**
4
+ * 開発環境用のデフォルト実装(console.log のみ)
5
+ * プラットフォーム側が実装を注入しない場合に使用される
6
+ */
7
+ export const createDefaultTeleportImplementation = () => ({
8
+ teleport: (destination) => console.log('[Teleport] teleport called', destination),
9
+ });
10
+ /**
11
+ * テレポート機能を提供する Context
12
+ * xrift-frontend 側で実装を注入し、ワールド側で利用できる
13
+ */
14
+ export const TeleportContext = createContext(null);
15
+ /**
16
+ * テレポート機能を提供する ContextProvider
17
+ */
18
+ export const TeleportProvider = ({ value, children }) => {
19
+ return _jsx(TeleportContext.Provider, { value: value, children: children });
20
+ };
21
+ /**
22
+ * テレポートの Context を取得する hook
23
+ * @throws {Error} TeleportProvider の外で呼び出された場合
24
+ */
25
+ export const useTeleportContext = () => {
26
+ const context = useContext(TeleportContext);
27
+ if (!context) {
28
+ throw new Error('useTeleportContext must be used within TeleportProvider');
29
+ }
30
+ return context;
31
+ };
32
+ //# sourceMappingURL=TeleportContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeleportContext.js","sourceRoot":"","sources":["../../src/contexts/TeleportContext.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,MAAM,OAAO,CAAA;AAYjE;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAyB,EAAE,CAAC,CAAC;IAC9E,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE,CACxB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,WAAW,CAAC;CACzD,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA8B,IAAI,CAAC,CAAA;AAO/E;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS,EAAE,EAAE;IAC7D,OAAO,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA4B,CAAA;AACtF,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAyB,EAAE;IAC3D,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAA;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;IAC5E,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { type TeleportDestination } from '../contexts/TeleportContext';
2
+ /**
3
+ * テレポート機能を使用するhook
4
+ * ワールド作成者がプレイヤーを瞬間移動させるために使用
5
+ *
6
+ * @example
7
+ * const { teleport } = useTeleport()
8
+ *
9
+ * // 位置と向きを指定してテレポート
10
+ * teleport({ position: [50, 0, 30], yaw: 180 })
11
+ *
12
+ * // 向きは省略可能(現在の向きを維持)
13
+ * teleport({ position: [50, 0, 30] })
14
+ *
15
+ * @returns {{ teleport: (destination: TeleportDestination) => void }}
16
+ */
17
+ export declare const useTeleport: () => {
18
+ teleport: (destination: TeleportDestination) => void;
19
+ };
20
+ //# sourceMappingURL=useTeleport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTeleport.d.ts","sourceRoot":"","sources":["../../src/hooks/useTeleport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,6BAA6B,CAAA;AAE1F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,QAAO;IAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAA;CAWpF,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { useCallback } from 'react';
2
+ import { useTeleportContext } from '../contexts/TeleportContext';
3
+ /**
4
+ * テレポート機能を使用するhook
5
+ * ワールド作成者がプレイヤーを瞬間移動させるために使用
6
+ *
7
+ * @example
8
+ * const { teleport } = useTeleport()
9
+ *
10
+ * // 位置と向きを指定してテレポート
11
+ * teleport({ position: [50, 0, 30], yaw: 180 })
12
+ *
13
+ * // 向きは省略可能(現在の向きを維持)
14
+ * teleport({ position: [50, 0, 30] })
15
+ *
16
+ * @returns {{ teleport: (destination: TeleportDestination) => void }}
17
+ */
18
+ export const useTeleport = () => {
19
+ const { teleport } = useTeleportContext();
20
+ const stableTeleport = useCallback((destination) => {
21
+ teleport(destination);
22
+ }, [teleport]);
23
+ return { teleport: stableTeleport };
24
+ };
25
+ //# sourceMappingURL=useTeleport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTeleport.js","sourceRoot":"","sources":["../../src/hooks/useTeleport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAA4B,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAE1F;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAA6D,EAAE;IACxF,MAAM,EAAE,QAAQ,EAAE,GAAG,kBAAkB,EAAE,CAAA;IAEzC,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,WAAgC,EAAE,EAAE;QACnC,QAAQ,CAAC,WAAW,CAAC,CAAA;IACvB,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAA;AACrC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xrift/world-components",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Shared components and utilities for Xrift worlds",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",