@cairntale/chimeling-react 1.0.0-alpha.1 → 1.0.0-alpha.2

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @cairntale/chimeling-react
2
2
 
3
+ ## 1.0.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 1cbe90a: Export utility functions and types including `getShowablePresence`, `formatActivityDuration`, and `iconImageUrl`
8
+ - 1cbe90a: Add `ChimelingPlayground` component for interactive testing and development
9
+ - 1cbe90a: Add Emotion CSS-in-JS integration to `ChimelingProvider` with `nonce` support
10
+
3
11
  ## 1.0.0-alpha.1
4
12
 
5
13
  ### Patch Changes
@@ -1,7 +1,7 @@
1
- import { ChimelingProvider } from "./provider.js";
2
- import { PresenceActivity, ShowablePresence } from "../lib/showable-presence.js";
1
+ import { ChimelingProvider, ChimelingProviderProps } from "./provider.js";
3
2
  import { ChimelingRoot, ChimelingRootProps } from "./root.js";
4
3
  import { ChimelingTrigger, ChimelingTriggerProps } from "./trigger.js";
5
4
  import { ChimelingPopover, ChimelingPopoverProps } from "./popover.js";
6
5
  import { Chimeling } from "./chimeling.js";
7
- export { Chimeling, ChimelingPopover, type ChimelingPopoverProps, ChimelingProvider, ChimelingRoot, type ChimelingRootProps, ChimelingTrigger, type ChimelingTriggerProps, type PresenceActivity, type ShowablePresence };
6
+ import { ChimelingPlayground } from "./playground/playground.js";
7
+ export { Chimeling, ChimelingPlayground, ChimelingPopover, type ChimelingPopoverProps, ChimelingProvider, type ChimelingProviderProps, ChimelingRoot, type ChimelingRootProps, ChimelingTrigger, type ChimelingTriggerProps };
@@ -4,4 +4,6 @@ import { ChimelingRoot } from "./root.js";
4
4
  import { ChimelingTrigger } from "./trigger.js";
5
5
  import { ChimelingPopover } from "./popover.js";
6
6
  import { Chimeling } from "./chimeling.js";
7
- export { Chimeling, ChimelingPopover, ChimelingProvider, ChimelingRoot, ChimelingTrigger };
7
+ import { ChimelingPlayground } from "./playground/playground.js";
8
+ import "./playground/index.js";
9
+ export { Chimeling, ChimelingPlayground, ChimelingPopover, ChimelingProvider, ChimelingRoot, ChimelingTrigger };
@@ -0,0 +1,2 @@
1
+ import { ChimelingPlayground } from "./playground.js";
2
+ export { ChimelingPlayground };
@@ -0,0 +1,173 @@
1
+ "use client";
2
+ import useTweaks from "./store.js";
3
+ import { ClassNames, Global } from "@emotion/react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import dialkitStyles from "dialkit/styles.css?raw";
6
+ import { ButtonGroup, Folder, SelectControl, Slider, TextControl, Toggle } from "dialkit";
7
+ //#region src/components/playground/panel.tsx
8
+ function PlaygroundPanel() {
9
+ const tweaks = useTweaks();
10
+ return /* @__PURE__ */ jsx(ClassNames, { children: ({ css, cx }) => /* @__PURE__ */ jsxs("div", {
11
+ className: cx("dialkit-root", css({
12
+ width: 320,
13
+ display: "flex",
14
+ flexDirection: "column",
15
+ gap: "var(--dial-row-gap)",
16
+ position: "fixed",
17
+ top: "calc(var(--dial-row-gap) * 1.5)",
18
+ right: "calc(var(--dial-row-gap) * 1.5)",
19
+ boxShadow: "var(--dial-shadow)",
20
+ background: "var(--dial-glass-bg)",
21
+ border: "1px solid var(--dial-border)",
22
+ backdropFilter: "blur(var(--dial-backdrop-blur))",
23
+ padding: "calc(var(--dial-row-gap) * 1.5)",
24
+ borderRadius: 14
25
+ })),
26
+ "data-theme": "system",
27
+ children: [
28
+ /* @__PURE__ */ jsx(Global, { styles: dialkitStyles }),
29
+ /* @__PURE__ */ jsx(SelectControl, {
30
+ label: "Mode",
31
+ value: tweaks.mode,
32
+ options: [{
33
+ label: "Live",
34
+ value: "live"
35
+ }, {
36
+ label: "Mock",
37
+ value: "mock"
38
+ }],
39
+ onChange: (v) => tweaks.set("mode", v)
40
+ }),
41
+ tweaks.mode === "live" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(TextControl, {
42
+ label: "Base URL",
43
+ value: tweaks.baseUrl,
44
+ onChange: (v) => tweaks.set("baseUrl", v)
45
+ }), /* @__PURE__ */ jsx(TextControl, {
46
+ label: "User ID",
47
+ value: tweaks.userId,
48
+ onChange: (v) => tweaks.set("userId", v)
49
+ })] }),
50
+ tweaks.mode === "mock" && /* @__PURE__ */ jsxs(Folder, {
51
+ title: "Presence",
52
+ children: [/* @__PURE__ */ jsx(SelectControl, {
53
+ label: "Status",
54
+ value: tweaks.presence.status,
55
+ options: [
56
+ {
57
+ label: "Online",
58
+ value: "online"
59
+ },
60
+ {
61
+ label: "Idle",
62
+ value: "idle"
63
+ },
64
+ {
65
+ label: "Offline",
66
+ value: "offline"
67
+ }
68
+ ],
69
+ onChange: (v) => tweaks.set("presence.status", v)
70
+ }), tweaks.presence.status !== "offline" && tweaks.presence.activity !== null && /* @__PURE__ */ jsxs(Fragment, { children: [
71
+ /* @__PURE__ */ jsx(TextControl, {
72
+ label: "Gerund",
73
+ value: tweaks.presence.activity.gerund,
74
+ onChange: (v) => tweaks.set("presence.activity.gerund", v)
75
+ }),
76
+ /* @__PURE__ */ jsx(TextControl, {
77
+ label: "App Name",
78
+ value: tweaks.presence.activity.appName,
79
+ onChange: (v) => tweaks.set("presence.activity.appName", v)
80
+ }),
81
+ /* @__PURE__ */ jsx(TextControl, {
82
+ label: "Icon Hash",
83
+ value: tweaks.presence.activity.iconHash,
84
+ onChange: (v) => tweaks.set("presence.activity.iconHash", v)
85
+ })
86
+ ] })]
87
+ }),
88
+ /* @__PURE__ */ jsxs(Folder, {
89
+ title: "Behavior",
90
+ children: [
91
+ /* @__PURE__ */ jsx(SelectControl, {
92
+ label: "Side",
93
+ value: tweaks.behavior.side,
94
+ options: [
95
+ {
96
+ label: "Top",
97
+ value: "top"
98
+ },
99
+ {
100
+ label: "Bottom",
101
+ value: "bottom"
102
+ },
103
+ {
104
+ label: "Left",
105
+ value: "left"
106
+ },
107
+ {
108
+ label: "Right",
109
+ value: "right"
110
+ },
111
+ {
112
+ label: "Inline Start",
113
+ value: "inline-start"
114
+ },
115
+ {
116
+ label: "Inline End",
117
+ value: "inline-end"
118
+ }
119
+ ],
120
+ onChange: (v) => tweaks.set("behavior.side", v)
121
+ }),
122
+ /* @__PURE__ */ jsx(SelectControl, {
123
+ label: "Align",
124
+ value: tweaks.behavior.align,
125
+ options: [
126
+ {
127
+ label: "Start",
128
+ value: "start"
129
+ },
130
+ {
131
+ label: "Center",
132
+ value: "center"
133
+ },
134
+ {
135
+ label: "End",
136
+ value: "end"
137
+ }
138
+ ],
139
+ onChange: (v) => tweaks.set("behavior.align", v)
140
+ }),
141
+ /* @__PURE__ */ jsx(Toggle, {
142
+ label: "Open on Hover",
143
+ checked: tweaks.behavior.openOnHover,
144
+ onChange: (v) => tweaks.set("behavior.openOnHover", v)
145
+ }),
146
+ tweaks.behavior.openOnHover && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Slider, {
147
+ label: "Hover Open Delay",
148
+ min: 0,
149
+ max: 1500,
150
+ step: 100,
151
+ value: tweaks.behavior.hoverOpenDelay,
152
+ onChange: (v) => tweaks.set("behavior.hoverOpenDelay", v)
153
+ }), /* @__PURE__ */ jsx(Slider, {
154
+ label: "Hover Close Delay",
155
+ min: 0,
156
+ max: 1500,
157
+ step: 100,
158
+ value: tweaks.behavior.hoverCloseDelay,
159
+ onChange: (v) => tweaks.set("behavior.hoverCloseDelay", v)
160
+ })] })
161
+ ]
162
+ }),
163
+ /* @__PURE__ */ jsx(ButtonGroup, { buttons: [{
164
+ label: "Reset",
165
+ onClick: tweaks.reset
166
+ }] })
167
+ ]
168
+ }) });
169
+ }
170
+ //#endregion
171
+ export { PlaygroundPanel };
172
+
173
+ //# sourceMappingURL=panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.js","names":[],"sources":["../../../src/components/playground/panel.tsx"],"sourcesContent":["'use client'\n\nimport dialkitStyles from 'dialkit/styles.css?raw'\nimport { Global, ClassNames } from '@emotion/react'\nimport { TextControl, SelectControl, Folder, Toggle, Slider, ButtonGroup } from 'dialkit'\nimport useTweaks from './store'\n\nexport function PlaygroundPanel() {\n const tweaks = useTweaks()\n\n return (\n <ClassNames>\n {({ css, cx }) => (\n <div\n className={cx(\n 'dialkit-root',\n css({\n width: 320,\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--dial-row-gap)',\n position: 'fixed',\n top: 'calc(var(--dial-row-gap) * 1.5)',\n right: 'calc(var(--dial-row-gap) * 1.5)',\n boxShadow: 'var(--dial-shadow)',\n background: 'var(--dial-glass-bg)',\n border: '1px solid var(--dial-border)',\n backdropFilter: 'blur(var(--dial-backdrop-blur))',\n padding: 'calc(var(--dial-row-gap) * 1.5)',\n borderRadius: 14,\n }),\n )}\n data-theme=\"system\"\n >\n <Global styles={dialkitStyles} />\n <SelectControl\n label=\"Mode\"\n value={tweaks.mode}\n options={[\n {\n label: 'Live',\n value: 'live',\n },\n { label: 'Mock', value: 'mock' },\n ]}\n onChange={v => tweaks.set('mode', v)}\n />\n {tweaks.mode === 'live' && (\n <>\n <TextControl\n label=\"Base URL\"\n value={tweaks.baseUrl}\n onChange={v => tweaks.set('baseUrl', v)}\n />\n <TextControl\n label=\"User ID\"\n value={tweaks.userId}\n onChange={v => tweaks.set('userId', v)}\n />\n </>\n )}\n {tweaks.mode === 'mock' && (\n <Folder title=\"Presence\">\n <SelectControl\n label=\"Status\"\n value={tweaks.presence.status}\n options={[\n {\n label: 'Online',\n value: 'online',\n },\n { label: 'Idle', value: 'idle' },\n { label: 'Offline', value: 'offline' },\n ]}\n onChange={v => tweaks.set('presence.status', v)}\n />\n {tweaks.presence.status !== 'offline' && tweaks.presence.activity !== null && (\n <>\n <TextControl\n label=\"Gerund\"\n value={tweaks.presence.activity.gerund}\n onChange={v => tweaks.set('presence.activity.gerund', v)}\n />\n <TextControl\n label=\"App Name\"\n value={tweaks.presence.activity.appName}\n onChange={v => tweaks.set('presence.activity.appName', v)}\n />\n <TextControl\n label=\"Icon Hash\"\n value={tweaks.presence.activity.iconHash!}\n onChange={v => tweaks.set('presence.activity.iconHash', v)}\n />\n </>\n )}\n </Folder>\n )}\n <Folder title=\"Behavior\">\n <SelectControl\n label=\"Side\"\n value={tweaks.behavior.side}\n options={[\n { label: 'Top', value: 'top' },\n { label: 'Bottom', value: 'bottom' },\n { label: 'Left', value: 'left' },\n { label: 'Right', value: 'right' },\n { label: 'Inline Start', value: 'inline-start' },\n { label: 'Inline End', value: 'inline-end' },\n ]}\n onChange={v => tweaks.set('behavior.side', v)}\n />\n <SelectControl\n label=\"Align\"\n value={tweaks.behavior.align}\n options={[\n { label: 'Start', value: 'start' },\n { label: 'Center', value: 'center' },\n { label: 'End', value: 'end' },\n ]}\n onChange={v => tweaks.set('behavior.align', v)}\n />\n <Toggle\n label=\"Open on Hover\"\n checked={tweaks.behavior.openOnHover}\n onChange={v => tweaks.set('behavior.openOnHover', v)}\n />\n {tweaks.behavior.openOnHover && (\n <>\n <Slider\n label=\"Hover Open Delay\"\n min={0}\n max={1500}\n step={100}\n value={tweaks.behavior.hoverOpenDelay}\n onChange={v => tweaks.set('behavior.hoverOpenDelay', v)}\n />\n <Slider\n label=\"Hover Close Delay\"\n min={0}\n max={1500}\n step={100}\n value={tweaks.behavior.hoverCloseDelay}\n onChange={v => tweaks.set('behavior.hoverCloseDelay', v)}\n />\n </>\n )}\n </Folder>\n <ButtonGroup buttons={[{ label: 'Reset', onClick: tweaks.reset }]} />\n </div>\n )}\n </ClassNames>\n )\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ //#region src/components/playground/playground.d.ts
2
+ type ChimelingPlaygroundProps = {
3
+ className?: string;
4
+ };
5
+ declare function ChimelingPlayground({ className }: ChimelingPlaygroundProps): import("react").JSX.Element;
6
+ //#endregion
7
+ export { ChimelingPlayground, ChimelingPlaygroundProps };
8
+ //# sourceMappingURL=playground.d.ts.map
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { ChimelingProvider } from "../provider.js";
3
+ import { Chimeling } from "../chimeling.js";
4
+ import useTweaks from "./store.js";
5
+ import { PlaygroundPanel } from "./panel.js";
6
+ import { ClassNames } from "@emotion/react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/playground/playground.tsx
9
+ function ChimelingPlayground({ className }) {
10
+ const tweaks = useTweaks();
11
+ return /* @__PURE__ */ jsx(ClassNames, { children: ({ css, cx }) => /* @__PURE__ */ jsxs("div", {
12
+ className: cx(css({
13
+ display: "flex",
14
+ alignItems: "center",
15
+ justifyContent: "center"
16
+ }), className),
17
+ children: [/* @__PURE__ */ jsx(PlaygroundPanel, {}), /* @__PURE__ */ jsx(ChimelingProvider, {
18
+ baseUrl: tweaks.baseUrl,
19
+ children: /* @__PURE__ */ jsxs(Chimeling.Root, {
20
+ userId: tweaks.userId,
21
+ presence: tweaks.mode === "mock" ? tweaks.presence : void 0,
22
+ side: tweaks.behavior.side,
23
+ align: tweaks.behavior.align,
24
+ openOnHover: tweaks.behavior.openOnHover,
25
+ hoverOpenDelay: tweaks.behavior.hoverOpenDelay,
26
+ hoverCloseDelay: tweaks.behavior.hoverCloseDelay,
27
+ children: [/* @__PURE__ */ jsx(Chimeling.Trigger, {}), /* @__PURE__ */ jsx(Chimeling.Popover, {})]
28
+ })
29
+ })]
30
+ }) });
31
+ }
32
+ //#endregion
33
+ export { ChimelingPlayground };
34
+
35
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","names":[],"sources":["../../../src/components/playground/playground.tsx"],"sourcesContent":["'use client'\n\nimport { ClassNames } from '@emotion/react'\nimport { Chimeling } from '../chimeling'\nimport { ChimelingProvider } from '../provider'\nimport { PlaygroundPanel } from './panel'\nimport useTweaks from './store'\n\nexport type ChimelingPlaygroundProps = {\n className?: string\n}\n\nexport function ChimelingPlayground({ className }: ChimelingPlaygroundProps) {\n const tweaks = useTweaks()\n\n return (\n <ClassNames>\n {({ css, cx }) => (\n <div\n className={cx(\n css({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }),\n className,\n )}\n >\n <PlaygroundPanel />\n <ChimelingProvider baseUrl={tweaks.baseUrl}>\n <Chimeling.Root\n userId={tweaks.userId}\n presence={tweaks.mode === 'mock' ? tweaks.presence : undefined}\n side={tweaks.behavior.side}\n align={tweaks.behavior.align}\n openOnHover={tweaks.behavior.openOnHover}\n hoverOpenDelay={tweaks.behavior.hoverOpenDelay}\n hoverCloseDelay={tweaks.behavior.hoverCloseDelay}\n >\n <Chimeling.Trigger />\n <Chimeling.Popover />\n </Chimeling.Root>\n </ChimelingProvider>\n </div>\n )}\n </ClassNames>\n )\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,oBAAoB,EAAE,aAAuC;CAC3E,MAAM,SAAS,UAAU;CAEzB,OACE,oBAAC,YAAD,EAAA,WACI,EAAE,KAAK,SACP,qBAAC,OAAD;EACE,WAAW,GACT,IAAI;GACF,SAAS;GACT,YAAY;GACZ,gBAAgB;EAClB,CAAC,GACD,SACF;EARF,UAAA,CAUE,oBAAC,iBAAD,CAAkB,CAAA,GAClB,oBAAC,mBAAD;GAAmB,SAAS,OAAO;GACjC,UAAA,qBAAC,UAAU,MAAX;IACE,QAAQ,OAAO;IACf,UAAU,OAAO,SAAS,SAAS,OAAO,WAAW,KAAA;IACrD,MAAM,OAAO,SAAS;IACtB,OAAO,OAAO,SAAS;IACvB,aAAa,OAAO,SAAS;IAC7B,gBAAgB,OAAO,SAAS;IAChC,iBAAiB,OAAO,SAAS;IAPnC,UAAA,CASE,oBAAC,UAAU,SAAX,CAAoB,CAAA,GACpB,oBAAC,UAAU,SAAX,CAAoB,CAAA,CACN;;EACC,CAAA,CAChB;CAEG,CAAA,EAAA,CAAA;AAEhB"}
@@ -0,0 +1,43 @@
1
+ import { create } from "zustand";
2
+ import { createJSONStorage, persist } from "zustand/middleware";
3
+ import { cloneDeep, get, set } from "es-toolkit/compat";
4
+ //#region src/components/playground/store.ts
5
+ const defaults = {
6
+ baseUrl: "https://chimeling.app",
7
+ userId: "user_3GA6hha0H3nrk9rTeCJ3pR6DcvY",
8
+ mode: "mock",
9
+ behavior: {
10
+ openOnHover: false,
11
+ hoverOpenDelay: 300,
12
+ hoverCloseDelay: 0,
13
+ side: "bottom",
14
+ align: "center"
15
+ },
16
+ presence: {
17
+ status: "online",
18
+ activity: {
19
+ gerund: "writing code",
20
+ appName: "Xcode",
21
+ iconHash: "9e769c255c3afb5b435502f8294229c78e7514cf51051c16ddf368d72f757b1d",
22
+ startedAt: /* @__PURE__ */ new Date()
23
+ }
24
+ }
25
+ };
26
+ const useTweaks = create()(persist((set$1, getState) => ({
27
+ ...defaults,
28
+ get: (path) => get(getState(), path),
29
+ set: (path, value) => set$1((state) => {
30
+ const next = cloneDeep(state);
31
+ set(next, path, value);
32
+ return next;
33
+ }),
34
+ reset: () => set$1(defaults)
35
+ }), {
36
+ name: "chimeling-playground",
37
+ storage: createJSONStorage(() => localStorage, { reviver: (key, value) => key === "startedAt" && typeof value === "string" ? new Date(value) : value }),
38
+ partialize: ({ get, set, reset, ...tweaks }) => tweaks
39
+ }));
40
+ //#endregion
41
+ export { useTweaks as default };
42
+
43
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","names":["lodashGet","set","lodashCloneDeep"],"sources":["../../../src/components/playground/store.ts"],"sourcesContent":["import { create } from 'zustand'\nimport { persist, createJSONStorage } from 'zustand/middleware'\nimport { get as lodashGet, set as lodashSet, cloneDeep as lodashCloneDeep } from 'es-toolkit/compat'\nimport type { GetResolvedUserPresenceResponse } from '@cairntale/chimeling-js'\nimport type { Chimeling } from '../chimeling'\n\ninterface Tweaks {\n baseUrl: string\n userId: string\n mode: 'live' | 'mock'\n behavior: Required<\n Pick<\n React.ComponentProps<typeof Chimeling.Root>,\n 'openOnHover' | 'hoverOpenDelay' | 'hoverCloseDelay' | 'align' | 'side'\n >\n >\n presence: GetResolvedUserPresenceResponse\n}\n\nconst NOW = new Date()\n\nconst defaults: Tweaks = {\n baseUrl: 'https://chimeling.app',\n userId: 'user_3GA6hha0H3nrk9rTeCJ3pR6DcvY',\n mode: 'mock',\n behavior: {\n openOnHover: false,\n hoverOpenDelay: 300,\n hoverCloseDelay: 0,\n side: 'bottom',\n align: 'center',\n },\n presence: {\n status: 'online',\n activity: {\n gerund: 'writing code',\n appName: 'Xcode',\n iconHash: '9e769c255c3afb5b435502f8294229c78e7514cf51051c16ddf368d72f757b1d',\n startedAt: NOW,\n },\n },\n}\n\nconst useTweaks = create<\n Tweaks & {\n get: (path: string) => any\n set: (path: string, value: any) => void\n reset: () => void\n }\n>()(\n persist(\n (set, getState) => ({\n ...defaults,\n get: (path: string): any => lodashGet(getState(), path),\n set: (path: string, value: any) =>\n set(state => {\n const next = lodashCloneDeep(state)\n lodashSet(next, path, value)\n return next\n }),\n reset: () => set(defaults),\n }),\n {\n name: 'chimeling-playground',\n storage: createJSONStorage(() => localStorage, {\n reviver: (key, value) =>\n key === 'startedAt' && typeof value === 'string' ? new Date(value) : value, // TODO: a more robust date parsing\n }),\n partialize: ({ get, set, reset, ...tweaks }) => tweaks,\n },\n ),\n)\n\nexport default useTweaks\n"],"mappings":";;;;AAqBA,MAAM,WAAmB;CACvB,SAAS;CACT,QAAQ;CACR,MAAM;CACN,UAAU;EACR,aAAa;EACb,gBAAgB;EAChB,iBAAiB;EACjB,MAAM;EACN,OAAO;CACT;CACA,UAAU;EACR,QAAQ;EACR,UAAU;GACR,QAAQ;GACR,SAAS;GACT,UAAU;GACV,2BAAW,IAnBD,KAmBG;EACf;CACF;AACF;AAEA,MAAM,YAAY,OAMhB,CAAC,CACD,SACG,OAAK,cAAc;CAClB,GAAG;CACH,MAAM,SAAsBA,IAAU,SAAS,GAAG,IAAI;CACtD,MAAM,MAAc,UAClBC,OAAI,UAAS;EACX,MAAM,OAAOC,UAAgB,KAAK;EAClC,IAAU,MAAM,MAAM,KAAK;EAC3B,OAAO;CACT,CAAC;CACH,aAAaD,MAAI,QAAQ;AAC3B,IACA;CACE,MAAM;CACN,SAAS,wBAAwB,cAAc,EAC7C,UAAU,KAAK,UACb,QAAQ,eAAe,OAAO,UAAU,WAAW,IAAI,KAAK,KAAK,IAAI,MACzE,CAAC;CACD,aAAa,EAAE,KAAK,KAAK,OAAO,GAAG,aAAa;AAClD,CACF,CACF"}
@@ -3,9 +3,10 @@ import { ReactNode } from "react";
3
3
  type ChimelingProviderProps = {
4
4
  baseUrl?: string;
5
5
  refreshInterval?: number;
6
- children: ReactNode;
6
+ children?: ReactNode;
7
+ nonce?: string;
7
8
  };
8
- declare function ChimelingProvider({ baseUrl, refreshInterval, children }: ChimelingProviderProps): import("react").JSX.Element;
9
+ declare function ChimelingProvider({ baseUrl, refreshInterval, children, nonce }: ChimelingProviderProps): import("react").JSX.Element;
9
10
  //#endregion
10
- export { ChimelingProvider };
11
+ export { ChimelingProvider, ChimelingProviderProps };
11
12
  //# sourceMappingURL=provider.d.ts.map
@@ -3,17 +3,31 @@ import { DEFAULT_PRESENCE_REFRESH_INTERVAL } from "../lib/config.js";
3
3
  import { ChimelingContext } from "../lib/context.js";
4
4
  import { useMemo } from "react";
5
5
  import { createClient, createConfig } from "@cairntale/chimeling-js/client";
6
+ import createCache from "@emotion/cache";
7
+ import { CacheProvider } from "@emotion/react";
6
8
  import { jsx } from "react/jsx-runtime";
7
9
  //#region src/components/provider.tsx
8
- function ChimelingProvider({ baseUrl, refreshInterval = DEFAULT_PRESENCE_REFRESH_INTERVAL, children }) {
10
+ function ChimelingProvider({ baseUrl, refreshInterval = DEFAULT_PRESENCE_REFRESH_INTERVAL, children, nonce }) {
9
11
  const client = useMemo(() => createClient(createConfig({ baseUrl: baseUrl ?? "https://chimeling.app" })), [baseUrl]);
10
12
  const value = useMemo(() => ({
11
13
  client,
12
14
  refreshInterval
13
15
  }), [client, refreshInterval]);
14
- return /* @__PURE__ */ jsx(ChimelingContext.Provider, {
15
- value,
16
- children
16
+ const emotionCache = useMemo(() => {
17
+ const insertionPoint = typeof document !== "undefined" ? document.querySelector(`style#chl-style-insertion-point`) ?? void 0 : void 0;
18
+ return createCache({
19
+ key: "chl-internal",
20
+ prepend: !insertionPoint,
21
+ insertionPoint,
22
+ nonce
23
+ });
24
+ }, [nonce]);
25
+ return /* @__PURE__ */ jsx(CacheProvider, {
26
+ value: emotionCache,
27
+ children: /* @__PURE__ */ jsx(ChimelingContext.Provider, {
28
+ value,
29
+ children
30
+ })
17
31
  });
18
32
  }
19
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","names":[],"sources":["../../src/components/provider.tsx"],"sourcesContent":["'use client'\n\nimport { useMemo, type ReactNode } from 'react'\nimport { createClient, createConfig } from '@cairntale/chimeling-js/client'\nimport { DEFAULT_PRESENCE_REFRESH_INTERVAL } from '../lib/config'\nimport { ChimelingContext } from '../lib/context'\n\ntype ChimelingProviderProps = {\n baseUrl?: string\n refreshInterval?: number\n children: ReactNode\n}\n\nexport function ChimelingProvider({\n baseUrl,\n refreshInterval = DEFAULT_PRESENCE_REFRESH_INTERVAL,\n children,\n}: ChimelingProviderProps) {\n const client = useMemo(\n () => createClient(createConfig({ baseUrl: baseUrl ?? 'https://chimeling.app' })),\n [baseUrl],\n )\n const value = useMemo(() => ({ client, refreshInterval }), [client, refreshInterval])\n\n return <ChimelingContext.Provider value={value}>{children}</ChimelingContext.Provider>\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,kBAAkB,EAChC,SACA,kBAAkB,mCAClB,YACyB;CACzB,MAAM,SAAS,cACP,aAAa,aAAa,EAAE,SAAS,WAAW,wBAAwB,CAAC,CAAC,GAChF,CAAC,OAAO,CACV;CACA,MAAM,QAAQ,eAAe;EAAE;EAAQ;CAAgB,IAAI,CAAC,QAAQ,eAAe,CAAC;CAEpF,OAAO,oBAAC,iBAAiB,UAAlB;EAAkC;EAAQ;CAAoC,CAAA;AACvF"}
1
+ {"version":3,"file":"provider.js","names":[],"sources":["../../src/components/provider.tsx"],"sourcesContent":["'use client'\n\nimport { useMemo, type ReactNode } from 'react'\nimport { createClient, createConfig } from '@cairntale/chimeling-js/client'\nimport { DEFAULT_PRESENCE_REFRESH_INTERVAL } from '../lib/config'\nimport { ChimelingContext } from '../lib/context'\nimport createCache from '@emotion/cache'\nimport { CacheProvider } from '@emotion/react'\n\nexport type ChimelingProviderProps = {\n baseUrl?: string\n refreshInterval?: number\n children?: ReactNode\n nonce?: string\n}\n\nexport function ChimelingProvider({\n baseUrl,\n refreshInterval = DEFAULT_PRESENCE_REFRESH_INTERVAL,\n children,\n nonce,\n}: ChimelingProviderProps) {\n const client = useMemo(\n () => createClient(createConfig({ baseUrl: baseUrl ?? 'https://chimeling.app' })),\n [baseUrl],\n )\n const value = useMemo(() => ({ client, refreshInterval }), [client, refreshInterval])\n\n const emotionCache = useMemo(() => {\n const insertionPoint =\n typeof document !== 'undefined'\n ? (document.querySelector<HTMLElement>(`style#chl-style-insertion-point`) ?? undefined)\n : undefined\n\n return createCache({\n key: 'chl-internal',\n prepend: !insertionPoint,\n insertionPoint,\n nonce,\n })\n }, [nonce])\n\n return (\n <CacheProvider value={emotionCache}>\n <ChimelingContext.Provider value={value}>{children}</ChimelingContext.Provider>\n </CacheProvider>\n )\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,kBAAkB,EAChC,SACA,kBAAkB,mCAClB,UACA,SACyB;CACzB,MAAM,SAAS,cACP,aAAa,aAAa,EAAE,SAAS,WAAW,wBAAwB,CAAC,CAAC,GAChF,CAAC,OAAO,CACV;CACA,MAAM,QAAQ,eAAe;EAAE;EAAQ;CAAgB,IAAI,CAAC,QAAQ,eAAe,CAAC;CAEpF,MAAM,eAAe,cAAc;EACjC,MAAM,iBACJ,OAAO,aAAa,cACf,SAAS,cAA2B,iCAAiC,KAAK,KAAA,IAC3E,KAAA;EAEN,OAAO,YAAY;GACjB,KAAK;GACL,SAAS,CAAC;GACV;GACA;EACF,CAAC;CACH,GAAG,CAAC,KAAK,CAAC;CAEV,OACE,oBAAC,eAAD;EAAe,OAAO;EACpB,UAAA,oBAAC,iBAAiB,UAAlB;GAAkC;GAAQ;EAAoC,CAAA;CACjE,CAAA;AAEnB"}
@@ -1,13 +1,18 @@
1
1
  "use client";
2
+ import { PACKAGE_NAME } from "../lib/config.js";
2
3
  import { useChimelingContext } from "../lib/context.js";
3
- import { resolvedUserPresenceKey } from "../lib/presence-key.js";
4
4
  import useSWR from "swr";
5
5
  import { getResolvedUserPresence } from "@cairntale/chimeling-js";
6
6
  //#region src/hooks/use-resolved-user-presence.ts
7
7
  function useResolvedUserPresence(userId, options) {
8
8
  const { client, refreshInterval } = useChimelingContext();
9
9
  const baseUrl = client.getConfig().baseUrl ?? "";
10
- return useSWR(userId ? resolvedUserPresenceKey(userId, baseUrl) : null, async ([, , , id]) => {
10
+ return useSWR(userId ? [
11
+ PACKAGE_NAME,
12
+ "resolved-user-presence",
13
+ baseUrl,
14
+ userId
15
+ ] : null, async ([, , , id]) => {
11
16
  const { data } = await getResolvedUserPresence({ userId: id }, {
12
17
  client,
13
18
  throwOnError: true
@@ -1 +1 @@
1
- {"version":3,"file":"use-resolved-user-presence.js","names":[],"sources":["../../src/hooks/use-resolved-user-presence.ts"],"sourcesContent":["'use client'\n\nimport useSWR from 'swr'\nimport { getResolvedUserPresence } from '@cairntale/chimeling-js'\nimport { useChimelingContext } from '../lib/context'\nimport { resolvedUserPresenceKey } from '../lib/presence-key'\n\nexport function useResolvedUserPresence(\n userId: string,\n options?: {\n refreshInterval?: number\n },\n) {\n const { client, refreshInterval } = useChimelingContext()\n const baseUrl = client.getConfig().baseUrl ?? ''\n\n return useSWR(\n userId ? resolvedUserPresenceKey(userId, baseUrl) : null,\n async ([, , , id]) => {\n const { data } = await getResolvedUserPresence({ userId: id }, { client, throwOnError: true })\n return data\n },\n {\n refreshInterval: options?.refreshInterval ?? refreshInterval,\n },\n )\n}\n"],"mappings":";;;;;;AAOA,SAAgB,wBACd,QACA,SAGA;CACA,MAAM,EAAE,QAAQ,oBAAoB,oBAAoB;CACxD,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC,WAAW;CAE9C,OAAO,OACL,SAAS,wBAAwB,QAAQ,OAAO,IAAI,MACpD,OAAO,OAAO,QAAQ;EACpB,MAAM,EAAE,SAAS,MAAM,wBAAwB,EAAE,QAAQ,GAAG,GAAG;GAAE;GAAQ,cAAc;EAAK,CAAC;EAC7F,OAAO;CACT,GACA,EACE,iBAAiB,SAAS,mBAAmB,gBAC/C,CACF;AACF"}
1
+ {"version":3,"file":"use-resolved-user-presence.js","names":[],"sources":["../../src/hooks/use-resolved-user-presence.ts"],"sourcesContent":["'use client'\n\nimport useSWR from 'swr'\nimport { getResolvedUserPresence } from '@cairntale/chimeling-js'\nimport { useChimelingContext } from '../lib/context'\nimport { PACKAGE_NAME } from '../lib/config'\n\nexport function useResolvedUserPresence(\n userId: string,\n options?: {\n refreshInterval?: number\n },\n) {\n const { client, refreshInterval } = useChimelingContext()\n const baseUrl = client.getConfig().baseUrl ?? ''\n\n return useSWR(\n userId ? [PACKAGE_NAME, 'resolved-user-presence', baseUrl, userId] : null,\n async ([, , , id]) => {\n const { data } = await getResolvedUserPresence({ userId: id }, { client, throwOnError: true })\n return data\n },\n {\n refreshInterval: options?.refreshInterval ?? refreshInterval,\n },\n )\n}\n"],"mappings":";;;;;;AAOA,SAAgB,wBACd,QACA,SAGA;CACA,MAAM,EAAE,QAAQ,oBAAoB,oBAAoB;CACxD,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC,WAAW;CAE9C,OAAO,OACL,SAAS;EAAC;EAAc;EAA0B;EAAS;CAAM,IAAI,MACrE,OAAO,OAAO,QAAQ;EACpB,MAAM,EAAE,SAAS,MAAM,wBAAwB,EAAE,QAAQ,GAAG,GAAG;GAAE;GAAQ,cAAc;EAAK,CAAC;EAC7F,OAAO;CACT,GACA,EACE,iBAAiB,SAAS,mBAAmB,gBAC/C,CACF;AACF"}
package/dist/index.d.ts CHANGED
@@ -1,11 +1,15 @@
1
- import { ChimelingProvider } from "./components/provider.js";
2
- import { PresenceActivity, ShowablePresence } from "./lib/showable-presence.js";
1
+ import { ChimelingProvider, ChimelingProviderProps } from "./components/provider.js";
2
+ import { PresenceActivity, ShowablePresence, getShowablePresence } from "./lib/showable-presence.js";
3
3
  import { ChimelingRoot, ChimelingRootProps } from "./components/root.js";
4
4
  import { ChimelingTrigger, ChimelingTriggerProps } from "./components/trigger.js";
5
5
  import { ChimelingPopover, ChimelingPopoverProps } from "./components/popover.js";
6
6
  import { Chimeling } from "./components/chimeling.js";
7
+ import { ChimelingPlayground } from "./components/playground/playground.js";
7
8
  import "./components/index.js";
8
9
  import { useChimelingClient } from "./hooks/use-client.js";
9
10
  import { useResolvedUserPresence } from "./hooks/use-resolved-user-presence.js";
10
11
  import "./hooks/index.js";
11
- export { Chimeling, ChimelingPopover, type ChimelingPopoverProps, ChimelingProvider, ChimelingRoot, type ChimelingRootProps, ChimelingTrigger, type ChimelingTriggerProps, type PresenceActivity, type ShowablePresence, useChimelingClient, useResolvedUserPresence };
12
+ import { formatActivityDuration } from "./lib/format-activity-duration.js";
13
+ import { iconImageUrl } from "./lib/icon-url.js";
14
+ import "./lib/index.js";
15
+ export { Chimeling, ChimelingPlayground, ChimelingPopover, type ChimelingPopoverProps, ChimelingProvider, type ChimelingProviderProps, ChimelingRoot, type ChimelingRootProps, ChimelingTrigger, type ChimelingTriggerProps, type PresenceActivity, type ShowablePresence, formatActivityDuration, getShowablePresence, iconImageUrl, useChimelingClient, useResolvedUserPresence };
package/dist/index.js CHANGED
@@ -1,11 +1,16 @@
1
1
  "use client";
2
2
  import { ChimelingProvider } from "./components/provider.js";
3
3
  import { useResolvedUserPresence } from "./hooks/use-resolved-user-presence.js";
4
+ import { getShowablePresence } from "./lib/showable-presence.js";
4
5
  import { ChimelingRoot } from "./components/root.js";
5
6
  import { ChimelingTrigger } from "./components/trigger.js";
7
+ import { formatActivityDuration } from "./lib/format-activity-duration.js";
8
+ import { iconImageUrl } from "./lib/icon-url.js";
6
9
  import { ChimelingPopover } from "./components/popover.js";
7
10
  import { Chimeling } from "./components/chimeling.js";
11
+ import { ChimelingPlayground } from "./components/playground/playground.js";
8
12
  import "./components/index.js";
9
13
  import { useChimelingClient } from "./hooks/use-client.js";
10
14
  import "./hooks/index.js";
11
- export { Chimeling, ChimelingPopover, ChimelingProvider, ChimelingRoot, ChimelingTrigger, useChimelingClient, useResolvedUserPresence };
15
+ import "./lib/index.js";
16
+ export { Chimeling, ChimelingPlayground, ChimelingPopover, ChimelingProvider, ChimelingRoot, ChimelingTrigger, formatActivityDuration, getShowablePresence, iconImageUrl, useChimelingClient, useResolvedUserPresence };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["packageJson.name"],"sources":["../../src/lib/config.ts"],"sourcesContent":["import packageJson from '../../package.json' with { type: 'json' }\n\nexport const PACKAGE_NAME = packageJson.name\n\nexport const DEFAULT_PRESENCE_REFRESH_INTERVAL = 5_000\n\nexport function packageErrorMessage(message: string): string {\n return `${PACKAGE_NAME}: ${message}`\n}\n"],"mappings":";;AAEA,MAAa,eAAeA;AAE5B,MAAa,oCAAoC;AAEjD,SAAgB,oBAAoB,SAAyB;CAC3D,OAAO,GAAG,aAAa,IAAI;AAC7B"}
1
+ {"version":3,"file":"config.js","names":["packageJson.name"],"sources":["../../src/lib/config.ts"],"sourcesContent":["import packageJson from '../../package.json' with { type: 'json' }\nexport const PACKAGE_NAME = packageJson.name\n\nexport const DEFAULT_PRESENCE_REFRESH_INTERVAL = 5000\n\nexport function packageErrorMessage(message: string): string {\n return `${PACKAGE_NAME}: ${message}`\n}\n"],"mappings":";;AACA,MAAa,eAAeA;AAE5B,MAAa,oCAAoC;AAEjD,SAAgB,oBAAoB,SAAyB;CAC3D,OAAO,GAAG,aAAa,IAAI;AAC7B"}
@@ -0,0 +1,5 @@
1
+ //#region src/lib/format-activity-duration.d.ts
2
+ declare function formatActivityDuration(startedAt: Date, now: Date): string;
3
+ //#endregion
4
+ export { formatActivityDuration };
5
+ //# sourceMappingURL=format-activity-duration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-activity-duration.js","names":[],"sources":["../../src/lib/format-activity-duration.ts"],"sourcesContent":["import { formatDuration, intervalToDuration } from 'date-fns'\n\nconst UNITS = ['years', 'months', 'weeks', 'days', 'hours', 'minutes'] as const\n\nconst JUST_NOW_MS = 60_000\n\nexport function formatActivityDuration(startedAt: Date, now: Date): string {\n const start = startedAt instanceof Date ? startedAt : new Date(startedAt)\n const elapsedMs = now.getTime() - start.getTime()\n if (elapsedMs < JUST_NOW_MS) {\n return 'just now'\n }\n\n const duration = intervalToDuration({ start, end: now })\n const unit = UNITS.find(name => (duration[name] ?? 0) > 0)\n if (!unit) {\n return 'just now'\n }\n\n return `for ${formatDuration({ [unit]: duration[unit] }, { format: [unit] })}`\n}\n"],"mappings":";;AAEA,MAAM,QAAQ;CAAC;CAAS;CAAU;CAAS;CAAQ;CAAS;AAAS;AAErE,MAAM,cAAc;AAEpB,SAAgB,uBAAuB,WAAiB,KAAmB;CACzE,MAAM,QAAQ,qBAAqB,OAAO,YAAY,IAAI,KAAK,SAAS;CAExE,IADkB,IAAI,QAAQ,IAAI,MAAM,QAAQ,IAChC,aACd,OAAO;CAGT,MAAM,WAAW,mBAAmB;EAAE;EAAO,KAAK;CAAI,CAAC;CACvD,MAAM,OAAO,MAAM,MAAK,UAAS,SAAS,SAAS,KAAK,CAAC;CACzD,IAAI,CAAC,MACH,OAAO;CAGT,OAAO,OAAO,eAAe,GAAG,OAAO,SAAS,MAAM,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC7E"}
1
+ {"version":3,"file":"format-activity-duration.js","names":[],"sources":["../../src/lib/format-activity-duration.ts"],"sourcesContent":["import { formatDuration, intervalToDuration } from 'date-fns'\n\nconst UNITS = ['years', 'months', 'weeks', 'days', 'hours', 'minutes'] as const\n\nconst JUST_NOW_MS = 60000\n\nexport function formatActivityDuration(startedAt: Date, now: Date): string {\n const start = startedAt instanceof Date ? startedAt : new Date(startedAt)\n const elapsedMs = now.getTime() - start.getTime()\n if (elapsedMs < JUST_NOW_MS) {\n return 'just now'\n }\n\n const duration = intervalToDuration({ start, end: now })\n const unit = UNITS.find(name => (duration[name] ?? 0) > 0)\n if (!unit) {\n return 'just now'\n }\n\n return `for ${formatDuration({ [unit]: duration[unit] }, { format: [unit] })}`\n}\n"],"mappings":";;AAEA,MAAM,QAAQ;CAAC;CAAS;CAAU;CAAS;CAAQ;CAAS;AAAS;AAErE,MAAM,cAAc;AAEpB,SAAgB,uBAAuB,WAAiB,KAAmB;CACzE,MAAM,QAAQ,qBAAqB,OAAO,YAAY,IAAI,KAAK,SAAS;CAExE,IADkB,IAAI,QAAQ,IAAI,MAAM,QAAQ,IAChC,aACd,OAAO;CAGT,MAAM,WAAW,mBAAmB;EAAE;EAAO,KAAK;CAAI,CAAC;CACvD,MAAM,OAAO,MAAM,MAAK,UAAS,SAAS,SAAS,KAAK,CAAC;CACzD,IAAI,CAAC,MACH,OAAO;CAGT,OAAO,OAAO,eAAe,GAAG,OAAO,SAAS,MAAM,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC7E"}
@@ -0,0 +1,5 @@
1
+ //#region src/lib/icon-url.d.ts
2
+ declare function iconImageUrl(baseUrl: string, hash: string): string;
3
+ //#endregion
4
+ export { iconImageUrl };
5
+ //# sourceMappingURL=icon-url.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { PresenceActivity, ShowablePresence, getShowablePresence } from "./showable-presence.js";
2
+ import { formatActivityDuration } from "./format-activity-duration.js";
3
+ import { iconImageUrl } from "./icon-url.js";
4
+ export { type PresenceActivity, type ShowablePresence, formatActivityDuration, getShowablePresence, iconImageUrl };
@@ -0,0 +1,4 @@
1
+ import { getShowablePresence } from "./showable-presence.js";
2
+ import { formatActivityDuration } from "./format-activity-duration.js";
3
+ import { iconImageUrl } from "./icon-url.js";
4
+ export { formatActivityDuration, getShowablePresence, iconImageUrl };
@@ -7,6 +7,7 @@ type PresenceActivity = NonNullable<PresenceWithActivity['activity']>;
7
7
  type ShowablePresence = Omit<PresenceWithActivity, 'activity'> & {
8
8
  activity: PresenceActivity;
9
9
  };
10
+ declare function getShowablePresence(presence: GetResolvedUserPresenceResponse | undefined): ShowablePresence | null;
10
11
  //#endregion
11
- export { PresenceActivity, ShowablePresence };
12
+ export { PresenceActivity, ShowablePresence, getShowablePresence };
12
13
  //# sourceMappingURL=showable-presence.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cairntale/chimeling-react",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.2",
4
4
  "private": false,
5
5
  "description": "Chimeling React library",
6
6
  "homepage": "https://chimeling.app/",
@@ -26,26 +26,37 @@
26
26
  "dependencies": {
27
27
  "@base-ui/react": "^1.7.0",
28
28
  "date-fns": "^4.4.0",
29
+ "dialkit": "^2.0.0",
30
+ "es-toolkit": "^1.52.0",
29
31
  "swr": "^2.3.6",
30
32
  "ufo": "^1.6.4",
33
+ "zustand": "^5.0.15",
31
34
  "@cairntale/chimeling-js": "1.0.0-alpha.1"
32
35
  },
33
36
  "devDependencies": {
34
37
  "@arethetypeswrong/core": "^0.18.5",
38
+ "@emotion/cache": "^11.14.0",
39
+ "@emotion/react": "^11.14.0",
35
40
  "@types/react": "^19.1.8",
36
41
  "@types/react-dom": "^19.1.6",
42
+ "motion": "^13.2.0",
37
43
  "publint": "^0.3.24",
38
44
  "react": "^19.1.0",
39
45
  "react-dom": "^19.1.0",
40
46
  "tsdown": "^0.22.14",
41
- "typescript": "6.0.3"
47
+ "typescript": "6.0.3",
48
+ "unplugin-raw": "^0.8.0"
42
49
  },
43
50
  "peerDependencies": {
51
+ "@emotion/cache": "^11.0.0",
52
+ "@emotion/react": "^11.0.0",
53
+ "motion": "^13.0.0",
44
54
  "react": "^18.0.0 || ^19.0.0",
45
55
  "react-dom": "^18.0.0 || ^19.0.0"
46
56
  },
47
57
  "scripts": {
48
58
  "build": "tsdown",
59
+ "dev": "tsdown --watch",
49
60
  "typecheck": "tsc"
50
61
  }
51
62
  }
@@ -1,14 +0,0 @@
1
- import { PACKAGE_NAME } from "./config.js";
2
- //#region src/lib/presence-key.ts
3
- function resolvedUserPresenceKey(userId, baseUrl) {
4
- return [
5
- PACKAGE_NAME,
6
- "resolved-user-presence",
7
- baseUrl,
8
- userId
9
- ];
10
- }
11
- //#endregion
12
- export { resolvedUserPresenceKey };
13
-
14
- //# sourceMappingURL=presence-key.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presence-key.js","names":[],"sources":["../../src/lib/presence-key.ts"],"sourcesContent":["import { PACKAGE_NAME } from './config'\n\nexport function resolvedUserPresenceKey(userId: string, baseUrl: string) {\n return [PACKAGE_NAME, 'resolved-user-presence', baseUrl, userId] as const\n}\n"],"mappings":";;AAEA,SAAgB,wBAAwB,QAAgB,SAAiB;CACvE,OAAO;EAAC;EAAc;EAA0B;EAAS;CAAM;AACjE"}