connectbase-client 1.10.0 → 2.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/CHANGELOG.md +162 -0
- package/MIGRATION-v2.md +149 -0
- package/README.md +23 -0
- package/dist/connect-base.umd.js +3 -3
- package/dist/index.d.mts +134 -22
- package/dist/index.d.ts +134 -22
- package/dist/index.js +100 -40
- package/dist/index.mjs +100 -40
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -1613,41 +1613,6 @@ var DatabaseAPI = class {
|
|
|
1613
1613
|
}
|
|
1614
1614
|
};
|
|
1615
1615
|
}
|
|
1616
|
-
/**
|
|
1617
|
-
* 프레즌스 상태 설정
|
|
1618
|
-
*/
|
|
1619
|
-
setPresence(status, device, metadata) {
|
|
1620
|
-
if (this.realtimeState !== "connected") return;
|
|
1621
|
-
this.sendRealtimeMessage({
|
|
1622
|
-
type: "presence_set",
|
|
1623
|
-
request_id: this.generateRequestId(),
|
|
1624
|
-
status,
|
|
1625
|
-
device,
|
|
1626
|
-
metadata
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
1629
|
-
/**
|
|
1630
|
-
* 프레즌스 구독 (다른 사용자의 온라인 상태 감시)
|
|
1631
|
-
*/
|
|
1632
|
-
subscribePresence(userIds, onPresence) {
|
|
1633
|
-
if (this.realtimeState !== "connected") return;
|
|
1634
|
-
this.realtimeHandlers.set("__presence__", {
|
|
1635
|
-
onSnapshot: (docs) => {
|
|
1636
|
-
const states = {};
|
|
1637
|
-
for (const doc of docs) {
|
|
1638
|
-
if (doc.data) {
|
|
1639
|
-
states[doc.id] = doc.data;
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
onPresence(states);
|
|
1643
|
-
}
|
|
1644
|
-
});
|
|
1645
|
-
this.sendRealtimeMessage({
|
|
1646
|
-
type: "presence_subscribe",
|
|
1647
|
-
request_id: this.generateRequestId(),
|
|
1648
|
-
user_ids: userIds
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
1616
|
/**
|
|
1652
1617
|
* 실시간 연결 상태 확인
|
|
1653
1618
|
*/
|
|
@@ -1689,7 +1654,7 @@ var DatabaseAPI = class {
|
|
|
1689
1654
|
this.setRealtimeState("connecting");
|
|
1690
1655
|
const baseUrl = this.realtimeOptions.dataServerUrl || this.http.getBaseUrl();
|
|
1691
1656
|
const wsUrl = baseUrl.replace(/^http/, "ws");
|
|
1692
|
-
const url = `${wsUrl}/v1/realtime/ws?access_token=${encodeURIComponent(this.realtimeOptions.accessToken)}`;
|
|
1657
|
+
const url = `${wsUrl}/v1/database/realtime/ws?access_token=${encodeURIComponent(this.realtimeOptions.accessToken)}`;
|
|
1693
1658
|
return new Promise((resolve, reject) => {
|
|
1694
1659
|
try {
|
|
1695
1660
|
this.realtimeWs = new WebSocket(url);
|
|
@@ -8346,15 +8311,31 @@ var AnalyticsAPI = class {
|
|
|
8346
8311
|
this.enqueue(event);
|
|
8347
8312
|
}
|
|
8348
8313
|
/**
|
|
8349
|
-
* 사용자 식별 (로그인
|
|
8350
|
-
*
|
|
8314
|
+
* 사용자 식별 (로그인 직후 호출).
|
|
8315
|
+
*
|
|
8316
|
+
* 이후 모든 방문 배치에 `app_member_id` 가 첨부되어 새 활동은 회원으로 기록됩니다.
|
|
8317
|
+
* 추가로 **현재 visitor_uid 의 기존 익명 활동을 즉시 회원에게 backfill** 하기 위해
|
|
8318
|
+
* 백엔드 `link-member` 엔드포인트를 한 번 호출합니다 (1.11.0+). 호출 실패는
|
|
8319
|
+
* silent — 다음 batch 가 닿을 때 백엔드 자동 매핑이 동일하게 처리하므로 자가 복구.
|
|
8320
|
+
*
|
|
8321
|
+
* 산업 표준(GA4 User-ID, Mixpanel/PostHog `identify`) 과 동작 정합.
|
|
8322
|
+
*
|
|
8323
|
+
* @example
|
|
8324
|
+
* ```ts
|
|
8325
|
+
* // 로그인 성공 직후
|
|
8326
|
+
* await cb.auth.signIn({ email, password })
|
|
8327
|
+
* cb.analytics.identify(member.id)
|
|
8328
|
+
* ```
|
|
8351
8329
|
*/
|
|
8352
8330
|
identify(memberId) {
|
|
8353
8331
|
this.setMemberId(memberId);
|
|
8332
|
+
this.linkMemberSilent(memberId);
|
|
8354
8333
|
}
|
|
8355
8334
|
/**
|
|
8356
|
-
* 방문자 트래커에 현재 회원 ID 설정 (로그인/게스트 가입 시 호출)
|
|
8357
|
-
*
|
|
8335
|
+
* 방문자 트래커에 현재 회원 ID 설정 (로그인/게스트 가입 시 호출).
|
|
8336
|
+
*
|
|
8337
|
+
* `identify()` 와 달리 즉시 backfill 호출은 하지 않습니다 — 단순히 이후 batch 의
|
|
8338
|
+
* `app_member_id` 값만 갱신. null 을 넘기면 익명 상태로 복귀 (로그아웃).
|
|
8358
8339
|
*/
|
|
8359
8340
|
setMemberId(memberId) {
|
|
8360
8341
|
this.memberId = memberId || null;
|
|
@@ -8371,6 +8352,25 @@ var AnalyticsAPI = class {
|
|
|
8371
8352
|
}
|
|
8372
8353
|
this.log("Member id set", { memberId });
|
|
8373
8354
|
}
|
|
8355
|
+
/**
|
|
8356
|
+
* 백엔드 link-member 엔드포인트 한 번 호출 — 즉시 backfill 트리거.
|
|
8357
|
+
*
|
|
8358
|
+
* - 첫 페이지뷰가 아직 백엔드에 닿기 전이면 visitor 가 없어 404. 무시 — 다음 batch 가
|
|
8359
|
+
* 가면 백엔드 BatchRecordVisit 가 자동 LinkMember 를 호출.
|
|
8360
|
+
* - storage_web_id 가 init 안 됐거나 모든 종류의 네트워크 오류 — silent fail.
|
|
8361
|
+
*/
|
|
8362
|
+
linkMemberSilent(memberId) {
|
|
8363
|
+
if (!this.storageWebId) return;
|
|
8364
|
+
const prefix = this.http.hasPublicKey() ? "/v1/public" : "/v1";
|
|
8365
|
+
this.http.post(
|
|
8366
|
+
`${prefix}/storages/web/${this.storageWebId}/visitors/link-member`,
|
|
8367
|
+
{
|
|
8368
|
+
visitor_uid: this.session.visitorUid,
|
|
8369
|
+
app_member_id: memberId
|
|
8370
|
+
}
|
|
8371
|
+
).catch(() => {
|
|
8372
|
+
});
|
|
8373
|
+
}
|
|
8374
8374
|
/** 현재 설정된 회원 ID 조회 (미설정 시 null) */
|
|
8375
8375
|
getMemberId() {
|
|
8376
8376
|
return this.memberId;
|
|
@@ -8502,6 +8502,66 @@ var AnalyticsAPI = class {
|
|
|
8502
8502
|
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
8503
8503
|
return this.http.get(`/v1/storages/web/${id}/visitors${qs}`);
|
|
8504
8504
|
}
|
|
8505
|
+
/**
|
|
8506
|
+
* 멤버별 합산 방문자 그룹 조회 — JWT/cb_sk_ 인증 필요. (1.11+)
|
|
8507
|
+
*
|
|
8508
|
+
* `getVisitors` 와 달리 visitor row 들을 `app_member_id` 로 합쳐 단일 row 로 반환.
|
|
8509
|
+
* 같은 사람이 PC + 모바일 + 태블릿으로 접속한 경우 visitor 3개 → 그룹 1개.
|
|
8510
|
+
* 익명 visitor 는 단일 row 로 그대로 포함되어 페이지네이션이 일관됨.
|
|
8511
|
+
*
|
|
8512
|
+
* @example
|
|
8513
|
+
* ```ts
|
|
8514
|
+
* const { groups } = await cb.analytics.getVisitorGroups('019d8...', { limit: 50 })
|
|
8515
|
+
* for (const g of groups) {
|
|
8516
|
+
* if (g.app_member_id) console.log(`${g.app_member_id}: ${g.visitor_count} 디바이스`)
|
|
8517
|
+
* }
|
|
8518
|
+
* ```
|
|
8519
|
+
*/
|
|
8520
|
+
async getVisitorGroups(storageWebId, options) {
|
|
8521
|
+
const id = this.requireServerSideStorageId(storageWebId, "getVisitorGroups");
|
|
8522
|
+
const params = new URLSearchParams();
|
|
8523
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
8524
|
+
if (options?.offset !== void 0) params.set("offset", String(options.offset));
|
|
8525
|
+
if (options?.sort_by) params.set("sort_by", options.sort_by);
|
|
8526
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
8527
|
+
return this.http.get(`/v1/storages/web/${id}/visitor-groups${qs}`);
|
|
8528
|
+
}
|
|
8529
|
+
/**
|
|
8530
|
+
* 단건 멤버 합산 방문자 조회 — JWT/cb_sk_ 인증 필요. (1.11+)
|
|
8531
|
+
*
|
|
8532
|
+
* 어드민 회원 상세 페이지처럼 **한 명만 필요**할 때. 페이지네이션 풀 다운 없이
|
|
8533
|
+
* 한 번의 호출로 합산 결과 반환.
|
|
8534
|
+
*
|
|
8535
|
+
* @example
|
|
8536
|
+
* ```ts
|
|
8537
|
+
* const v = await cb.analytics.getVisitorByMember('019d8...', memberId)
|
|
8538
|
+
* console.log(`${v.visitor_count} 디바이스, 총 ${v.total_page_views} pv`)
|
|
8539
|
+
* ```
|
|
8540
|
+
*/
|
|
8541
|
+
async getVisitorByMember(storageWebId, memberId) {
|
|
8542
|
+
const id = this.requireServerSideStorageId(storageWebId, "getVisitorByMember");
|
|
8543
|
+
return this.http.get(`/v1/storages/web/${id}/members/${memberId}/visitor`);
|
|
8544
|
+
}
|
|
8545
|
+
/**
|
|
8546
|
+
* 두 visitor 를 한 사람으로 통합하는 admin 작업 — JWT/cb_sk_ 인증 필요. (1.11+)
|
|
8547
|
+
*
|
|
8548
|
+
* 외부 인증 시스템에서 두 visitor 가 동일인임을 알았을 때 사용. source 의 자식 레코드
|
|
8549
|
+
* (page_views, daily, custom_events, experiment_assignments, heatmap_events,
|
|
8550
|
+
* session_recordings) 를 target 으로 옮기고 source visitor 는 삭제됨.
|
|
8551
|
+
*
|
|
8552
|
+
* @param request 둘 중 하나 필수: `target_visitor_uid` 또는 `target_member_id`.
|
|
8553
|
+
* @example
|
|
8554
|
+
* ```ts
|
|
8555
|
+
* await cb.analytics.mergeVisitors('019d8...', {
|
|
8556
|
+
* source_visitor_uid: 'old-uid',
|
|
8557
|
+
* target_member_id: '01a...',
|
|
8558
|
+
* })
|
|
8559
|
+
* ```
|
|
8560
|
+
*/
|
|
8561
|
+
async mergeVisitors(storageWebId, request) {
|
|
8562
|
+
const id = this.requireServerSideStorageId(storageWebId, "mergeVisitors");
|
|
8563
|
+
return this.http.post(`/v1/storages/web/${id}/visitors/merge`, request);
|
|
8564
|
+
}
|
|
8505
8565
|
/**
|
|
8506
8566
|
* 조회 메서드 공통 가드 — Public Key 인증 SDK 인스턴스에서는 명확한 에러를 던진다.
|
|
8507
8567
|
* 백엔드 라우트는 cb_pk_ 를 거부하므로 호출 자체를 막는 것이 디버깅에 유리.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "connectbase-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Connect Base JavaScript/TypeScript SDK for browser and Node.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"dist",
|
|
36
36
|
"LICENSE",
|
|
37
37
|
"CHANGELOG.md",
|
|
38
|
-
"README.md"
|
|
38
|
+
"README.md",
|
|
39
|
+
"MIGRATION-v2.md"
|
|
39
40
|
],
|
|
40
41
|
"scripts": {
|
|
41
42
|
"build": "tsup",
|