@chatlychat/react-native 0.0.0-stage → 0.1.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.
Files changed (114) hide show
  1. package/README.md +208 -2
  2. package/dist/ChatlyProvider.d.ts +69 -0
  3. package/dist/ChatlyProvider.d.ts.map +1 -0
  4. package/dist/ChatlyProvider.js +146 -0
  5. package/dist/ChatlyProvider.js.map +1 -0
  6. package/dist/ChatlyWidget.d.ts +15 -0
  7. package/dist/ChatlyWidget.d.ts.map +1 -0
  8. package/dist/ChatlyWidget.js +122 -0
  9. package/dist/ChatlyWidget.js.map +1 -0
  10. package/dist/blocks/money.d.ts +56 -0
  11. package/dist/blocks/money.d.ts.map +1 -0
  12. package/dist/blocks/money.js +82 -0
  13. package/dist/blocks/money.js.map +1 -0
  14. package/dist/blocks/money.parity.spec.d.ts +2 -0
  15. package/dist/blocks/money.parity.spec.d.ts.map +1 -0
  16. package/dist/blocks/money.parity.spec.js +87 -0
  17. package/dist/blocks/money.parity.spec.js.map +1 -0
  18. package/dist/blocks/read-envelope.d.ts +15 -0
  19. package/dist/blocks/read-envelope.d.ts.map +1 -0
  20. package/dist/blocks/read-envelope.js +196 -0
  21. package/dist/blocks/read-envelope.js.map +1 -0
  22. package/dist/blocks/read-envelope.parity.spec.d.ts +2 -0
  23. package/dist/blocks/read-envelope.parity.spec.d.ts.map +1 -0
  24. package/dist/blocks/read-envelope.parity.spec.js +146 -0
  25. package/dist/blocks/read-envelope.parity.spec.js.map +1 -0
  26. package/dist/blocks/types.d.ts +171 -0
  27. package/dist/blocks/types.d.ts.map +1 -0
  28. package/dist/blocks/types.js +3 -0
  29. package/dist/blocks/types.js.map +1 -0
  30. package/dist/client/RealtimeClient.d.ts +29 -0
  31. package/dist/client/RealtimeClient.d.ts.map +1 -0
  32. package/dist/client/RealtimeClient.js +113 -0
  33. package/dist/client/RealtimeClient.js.map +1 -0
  34. package/dist/client/RealtimeClient.spec.d.ts +2 -0
  35. package/dist/client/RealtimeClient.spec.d.ts.map +1 -0
  36. package/dist/client/RealtimeClient.spec.js +123 -0
  37. package/dist/client/RealtimeClient.spec.js.map +1 -0
  38. package/dist/client/RestClient.d.ts +160 -0
  39. package/dist/client/RestClient.d.ts.map +1 -0
  40. package/dist/client/RestClient.js +395 -0
  41. package/dist/client/RestClient.js.map +1 -0
  42. package/dist/client/RestClient.spec.d.ts +2 -0
  43. package/dist/client/RestClient.spec.d.ts.map +1 -0
  44. package/dist/client/RestClient.spec.js +267 -0
  45. package/dist/client/RestClient.spec.js.map +1 -0
  46. package/dist/client/types.d.ts +148 -0
  47. package/dist/client/types.d.ts.map +1 -0
  48. package/dist/client/types.js +14 -0
  49. package/dist/client/types.js.map +1 -0
  50. package/dist/components/Composer.d.ts +35 -0
  51. package/dist/components/Composer.d.ts.map +1 -0
  52. package/dist/components/Composer.js +180 -0
  53. package/dist/components/Composer.js.map +1 -0
  54. package/dist/components/HelpCenter.d.ts +13 -0
  55. package/dist/components/HelpCenter.d.ts.map +1 -0
  56. package/dist/components/HelpCenter.js +96 -0
  57. package/dist/components/HelpCenter.js.map +1 -0
  58. package/dist/components/MessageBlocks.d.ts +41 -0
  59. package/dist/components/MessageBlocks.d.ts.map +1 -0
  60. package/dist/components/MessageBlocks.js +167 -0
  61. package/dist/components/MessageBlocks.js.map +1 -0
  62. package/dist/components/MessageBubble.d.ts +14 -0
  63. package/dist/components/MessageBubble.d.ts.map +1 -0
  64. package/dist/components/MessageBubble.js +87 -0
  65. package/dist/components/MessageBubble.js.map +1 -0
  66. package/dist/components/MessageBubble.spec.d.ts +2 -0
  67. package/dist/components/MessageBubble.spec.d.ts.map +1 -0
  68. package/dist/components/MessageBubble.spec.js +207 -0
  69. package/dist/components/MessageBubble.spec.js.map +1 -0
  70. package/dist/components/MessageCanvas.d.ts +39 -0
  71. package/dist/components/MessageCanvas.d.ts.map +1 -0
  72. package/dist/components/MessageCanvas.js +144 -0
  73. package/dist/components/MessageCanvas.js.map +1 -0
  74. package/dist/components/MessageCanvas.spec.d.ts +2 -0
  75. package/dist/components/MessageCanvas.spec.d.ts.map +1 -0
  76. package/dist/components/MessageCanvas.spec.js +142 -0
  77. package/dist/components/MessageCanvas.spec.js.map +1 -0
  78. package/dist/components/MessagesList.d.ts +8 -0
  79. package/dist/components/MessagesList.d.ts.map +1 -0
  80. package/dist/components/MessagesList.js +58 -0
  81. package/dist/components/MessagesList.js.map +1 -0
  82. package/dist/index.d.ts +48 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +35 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/push/registerPushToken.d.ts +12 -0
  87. package/dist/push/registerPushToken.d.ts.map +1 -0
  88. package/dist/push/registerPushToken.js +32 -0
  89. package/dist/push/registerPushToken.js.map +1 -0
  90. package/dist/storage/TokenStore.d.ts +53 -0
  91. package/dist/storage/TokenStore.d.ts.map +1 -0
  92. package/dist/storage/TokenStore.js +89 -0
  93. package/dist/storage/TokenStore.js.map +1 -0
  94. package/dist/test/react-native-dom.d.ts +97 -0
  95. package/dist/test/react-native-dom.d.ts.map +1 -0
  96. package/dist/test/react-native-dom.js +155 -0
  97. package/dist/test/react-native-dom.js.map +1 -0
  98. package/dist/test/react-native-dom.spec.d.ts +2 -0
  99. package/dist/test/react-native-dom.spec.d.ts.map +1 -0
  100. package/dist/test/react-native-dom.spec.js +83 -0
  101. package/dist/test/react-native-dom.spec.js.map +1 -0
  102. package/dist/theme/ChatlyTheme.d.ts +37 -0
  103. package/dist/theme/ChatlyTheme.d.ts.map +1 -0
  104. package/dist/theme/ChatlyTheme.js +2 -0
  105. package/dist/theme/ChatlyTheme.js.map +1 -0
  106. package/dist/theme/defaultTheme.d.ts +7 -0
  107. package/dist/theme/defaultTheme.d.ts.map +1 -0
  108. package/dist/theme/defaultTheme.js +37 -0
  109. package/dist/theme/defaultTheme.js.map +1 -0
  110. package/dist/useChatly.d.ts +3 -0
  111. package/dist/useChatly.d.ts.map +1 -0
  112. package/dist/useChatly.js +10 -0
  113. package/dist/useChatly.js.map +1 -0
  114. package/package.json +50 -4
@@ -0,0 +1,155 @@
1
+ /**
2
+ * A DOM stand-in for the React Native primitives THIS package uses, so its
3
+ * components can be tested at all.
4
+ *
5
+ * ── Why this package needed one ────────────────────────────────────────
6
+ *
7
+ * `vitest.config.ts` here included `src/**‌/*.spec.ts`, which cannot match a
8
+ * `.tsx` file — so every component in a published SDK (the composer, the
9
+ * message list, and now the block and canvas renderers a shopper taps) was
10
+ * structurally untestable. The same one-line config bug that left
11
+ * `apps/mobile-agent`'s screens uncovered, in a package customers ship.
12
+ *
13
+ * ── Why it is a second stand-in and not a shared one ───────────────────
14
+ *
15
+ * `apps/mobile-agent/src/test/react-native-mock.tsx` is the same idea for the
16
+ * agent app, and sharing them was tried and reverted. The only place a
17
+ * workspace-shared version could live is `@livechat/testing`, which depends
18
+ * on `@livechat/db`, `postgres` and `testcontainers` — so every React Native
19
+ * package would take a Postgres driver into its dev graph to borrow a `<div>`
20
+ * wrapper, and a bare `@livechat/testing/react-native-dom` specifier does not
21
+ * resolve from an app that does not depend on it. The two files also cover
22
+ * genuinely different sets: that one has `Alert`, `Modal`, `Switch`,
23
+ * `Animated` and a navigation stub; this one has the twelve primitives this
24
+ * package imports and nothing else.
25
+ *
26
+ * The real risk of a local copy is not drift — neither file is a contract —
27
+ * it is a stand-in that silently lacks a primitive a component starts using,
28
+ * which makes that component untestable again. `react-native-dom.spec.tsx`
29
+ * reads every `from 'react-native'` import in this package's source and
30
+ * fails if any name is missing from here, which is the half that matters.
31
+ *
32
+ * ── What it does NOT prove ─────────────────────────────────────────────
33
+ *
34
+ * Nothing native: not layout, not gestures, not keyboard behaviour, not that
35
+ * a `Pressable` has a large enough hit area, not that the package builds for
36
+ * a device. What it covers is the React layer, which is where component bugs
37
+ * are.
38
+ *
39
+ * `accessibilityLabel` becomes `aria-label` and `testID` becomes
40
+ * `data-testid`, deliberately: a test then asks for an element the way a
41
+ * screen reader would, so a control that is unlabelled in the app is also
42
+ * unfindable in the test.
43
+ */
44
+ import React from 'react';
45
+ /**
46
+ * RN props that mean something to a DOM element, translated. Everything else
47
+ * — `style`, `keyboardType` and the rest — is dropped rather than passed
48
+ * through, because React would warn about each one and the warnings would
49
+ * bury a real failure.
50
+ */
51
+ function domProps(props) {
52
+ const out = {};
53
+ if (typeof props['accessibilityLabel'] === 'string') {
54
+ out['aria-label'] = props['accessibilityLabel'];
55
+ }
56
+ if (typeof props['accessibilityHint'] === 'string') {
57
+ out['aria-description'] = props['accessibilityHint'];
58
+ }
59
+ if (typeof props['testID'] === 'string') {
60
+ out['data-testid'] = props['testID'];
61
+ }
62
+ if (props['accessibilityRole'] === 'button' || props['accessibilityRole'] === 'link') {
63
+ out['role'] = props['accessibilityRole'];
64
+ }
65
+ if (props['disabled'] === true) {
66
+ out['disabled'] = true;
67
+ out['aria-disabled'] = true;
68
+ }
69
+ return out;
70
+ }
71
+ function view(tag) {
72
+ return function Mock(props) {
73
+ return React.createElement(tag, domProps(props), props['children']);
74
+ };
75
+ }
76
+ export const View = view('div');
77
+ export const SafeAreaView = view('div');
78
+ export const ScrollView = view('div');
79
+ export const Text = view('span');
80
+ export const ActivityIndicator = function ActivityIndicator(props) {
81
+ return React.createElement('progress', domProps(props));
82
+ };
83
+ export const Image = function Image(props) {
84
+ const source = props['source'];
85
+ return React.createElement('img', {
86
+ ...domProps(props),
87
+ src: source?.uri ?? '',
88
+ // RN has no alt; `accessibilityLabel` is the equivalent and an image with
89
+ // neither should be findable as decorative rather than invisible.
90
+ alt: typeof props['accessibilityLabel'] === 'string' ? props['accessibilityLabel'] : '',
91
+ });
92
+ };
93
+ /**
94
+ * `Pressable` as a real `<button>`.
95
+ *
96
+ * A `<div onClick>` would be clickable in a test and unreachable by keyboard,
97
+ * which is exactly the distinction a test should keep: `getByRole('button')`
98
+ * finds this, and `userEvent.click` fires `onPress`.
99
+ */
100
+ const pressable = function Pressable(props) {
101
+ const onPress = props['onPress'];
102
+ return React.createElement('button', {
103
+ ...domProps(props),
104
+ type: 'button',
105
+ onClick: typeof onPress === 'function' ? onPress : undefined,
106
+ }, props['children']);
107
+ };
108
+ export const Pressable = pressable;
109
+ export const TouchableOpacity = pressable;
110
+ export const TextInput = function TextInput(props) {
111
+ const onChangeText = props['onChangeText'];
112
+ return React.createElement('input', {
113
+ ...domProps(props),
114
+ value: props['value'] ?? '',
115
+ placeholder: props['placeholder'],
116
+ onChange: (e) => {
117
+ if (typeof onChangeText === 'function') {
118
+ onChangeText(e.target.value);
119
+ }
120
+ },
121
+ });
122
+ };
123
+ /**
124
+ * `FlatList` rendered eagerly, every row.
125
+ *
126
+ * A virtualising list would render a window, and a test asserting "the row is
127
+ * there" would then depend on a measured viewport that jsdom does not have.
128
+ * Every row is the honest simplification: it can over-report (a row present
129
+ * here might be off-screen on a device) and it cannot under-report, which is
130
+ * the direction a test should fail in.
131
+ */
132
+ export const FlatList = function FlatList(props) {
133
+ const data = props['data'] ?? [];
134
+ const renderItem = props['renderItem'];
135
+ const keyExtractor = props['keyExtractor'];
136
+ return React.createElement('div', domProps(props), props['ListHeaderComponent'], data.length === 0
137
+ ? props['ListEmptyComponent']
138
+ : data.map((item, index) => React.createElement('div', { key: keyExtractor?.(item, index) ?? String(index) }, renderItem?.({ item, index }))), props['ListFooterComponent']);
139
+ };
140
+ export const Platform = { OS: 'ios', select: (o) => o['ios'] };
141
+ export const StyleSheet = {
142
+ create: (styles) => styles,
143
+ hairlineWidth: 1,
144
+ flatten: (s) => s,
145
+ absoluteFill: {},
146
+ };
147
+ /** Opening a url. Recorded rather than performed, so a test can assert it. */
148
+ export const openedUrls = [];
149
+ export const Linking = {
150
+ openURL: async (url) => {
151
+ openedUrls.push(url);
152
+ },
153
+ canOpenURL: async () => true,
154
+ };
155
+ //# sourceMappingURL=react-native-dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-dom.js","sourceRoot":"","sources":["../../src/test/react-native-dom.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=react-native-dom.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-dom.spec.d.ts","sourceRoot":"","sources":["../../src/test/react-native-dom.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The DOM stand-in covers every primitive this package imports.
3
+ *
4
+ * ── The failure this catches ───────────────────────────────────────────
5
+ *
6
+ * A stand-in is not a contract, so it cannot "drift" in the usual sense.
7
+ * What it can do is silently lack a primitive a component starts using:
8
+ * `import { Modal } from 'react-native'` resolves to `undefined`, the
9
+ * component throws at render, and the symptom is a test file that fails to
10
+ * collect — which reads as a broken test rather than as an incomplete
11
+ * harness. Worse, somebody deletes the test.
12
+ *
13
+ * So this reads the source rather than trusting it: every name imported from
14
+ * `react-native` anywhere in `src/` must be exported by the stand-in.
15
+ */
16
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
17
+ import { dirname, join } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { describe, expect, it } from 'vitest';
20
+ import * as standIn from './react-native-dom';
21
+ /*
22
+ * `fileURLToPath(dirname(...))`, not `new URL('..').pathname`.
23
+ *
24
+ * The first attempt used the latter and resolved to `/src` — vite rewrites
25
+ * `import.meta.url` for a transformed module, so the URL is root-relative and
26
+ * `.pathname` drops the part that matters. The failure was an ENOENT on
27
+ * `/src/index.ts`, which at least was loud; a version that had silently
28
+ * scanned an empty directory would have passed.
29
+ */
30
+ const SRC = dirname(dirname(fileURLToPath(import.meta.url)));
31
+ function walk(dir, out = []) {
32
+ for (const entry of readdirSync(dir)) {
33
+ const full = join(dir, entry);
34
+ if (statSync(full).isDirectory()) {
35
+ walk(full, out);
36
+ }
37
+ else if (/\.tsx?$/.test(entry) && !entry.includes('.spec.')) {
38
+ out.push(full);
39
+ }
40
+ }
41
+ return out;
42
+ }
43
+ /** Every name imported from `react-native`, across the package. */
44
+ function importedNames() {
45
+ const names = new Set();
46
+ for (const file of walk(SRC)) {
47
+ const src = readFileSync(file, 'utf8');
48
+ for (const m of src.matchAll(/import \{([^}]*)\} from 'react-native';/gs)) {
49
+ for (const raw of (m[1] ?? '').split(',')) {
50
+ const name = raw.trim().replace(/^type\s+/, '');
51
+ if (name.length > 0) {
52
+ names.add(name);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ return [...names].sort();
58
+ }
59
+ describe('react-native stand-in', () => {
60
+ const imported = importedNames();
61
+ it('is reading the source — the scan found the imports', () => {
62
+ // A floor, because an empty list would make the assertion below trivially
63
+ // true forever. Twelve at the time of writing.
64
+ expect(imported.length).toBeGreaterThanOrEqual(10);
65
+ expect(imported).toContain('View');
66
+ expect(imported).toContain('Text');
67
+ });
68
+ it('exports every primitive the package imports', () => {
69
+ // `ListRenderItemInfo` is a TYPE and is erased, so it is not a runtime
70
+ // export of the stand-in — but it must still be declared there or the
71
+ // alias breaks the typecheck, which `tsc --noEmit` covers.
72
+ const runtime = imported.filter((n) => n !== 'ListRenderItemInfo');
73
+ const missing = runtime.filter((n) => !(n in standIn));
74
+ expect(missing).toEqual([]);
75
+ });
76
+ it('exports components that actually render', () => {
77
+ // `in` would be satisfied by an exported `undefined`.
78
+ for (const name of ['View', 'Text', 'Pressable', 'TextInput', 'FlatList', 'Image']) {
79
+ expect(typeof standIn[name]).toBe('function');
80
+ }
81
+ });
82
+ });
83
+ //# sourceMappingURL=react-native-dom.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-dom.spec.js","sourceRoot":"","sources":["../../src/test/react-native-dom.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Theme contract. Mirrors the variables exposed by the web widget so designers
3
+ * can theme web + mobile from one palette.
4
+ */
5
+ export interface ChatlyTheme {
6
+ colors: {
7
+ primary: string;
8
+ onPrimary: string;
9
+ background: string;
10
+ foreground: string;
11
+ mutedForeground: string;
12
+ border: string;
13
+ surface: string;
14
+ danger: string;
15
+ };
16
+ radius: {
17
+ sm: number;
18
+ md: number;
19
+ lg: number;
20
+ bubble: number;
21
+ };
22
+ spacing: {
23
+ xs: number;
24
+ sm: number;
25
+ md: number;
26
+ lg: number;
27
+ };
28
+ typography: {
29
+ sizeBody: number;
30
+ sizeSmall: number;
31
+ sizeTitle: number;
32
+ weightRegular: '400';
33
+ weightMedium: '500';
34
+ weightBold: '700';
35
+ };
36
+ }
37
+ //# sourceMappingURL=ChatlyTheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatlyTheme.d.ts","sourceRoot":"","sources":["../../src/theme/ChatlyTheme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,KAAK,CAAC;QACrB,YAAY,EAAE,KAAK,CAAC;QACpB,UAAU,EAAE,KAAK,CAAC;KACnB,CAAC;CACH"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ChatlyTheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatlyTheme.js","sourceRoot":"","sources":["../../src/theme/ChatlyTheme.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { ChatlyTheme } from './ChatlyTheme';
2
+ /**
3
+ * Default theme. Colors mirror the web widget defaults so cross-platform
4
+ * branding stays consistent out of the box.
5
+ */
6
+ export declare const defaultTheme: ChatlyTheme;
7
+ //# sourceMappingURL=defaultTheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultTheme.d.ts","sourceRoot":"","sources":["../../src/theme/defaultTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,WA+B1B,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Default theme. Colors mirror the web widget defaults so cross-platform
3
+ * branding stays consistent out of the box.
4
+ */
5
+ export const defaultTheme = {
6
+ colors: {
7
+ primary: '#2563eb',
8
+ onPrimary: '#ffffff',
9
+ background: '#ffffff',
10
+ foreground: '#0f172a',
11
+ mutedForeground: '#64748b',
12
+ border: '#e2e8f0',
13
+ surface: '#f8fafc',
14
+ danger: '#ef4444',
15
+ },
16
+ radius: {
17
+ sm: 6,
18
+ md: 10,
19
+ lg: 16,
20
+ bubble: 18,
21
+ },
22
+ spacing: {
23
+ xs: 4,
24
+ sm: 8,
25
+ md: 12,
26
+ lg: 16,
27
+ },
28
+ typography: {
29
+ sizeBody: 15,
30
+ sizeSmall: 12,
31
+ sizeTitle: 17,
32
+ weightRegular: '400',
33
+ weightMedium: '500',
34
+ weightBold: '700',
35
+ },
36
+ };
37
+ //# sourceMappingURL=defaultTheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultTheme.js","sourceRoot":"","sources":["../../src/theme/defaultTheme.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAgB;IACvC,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;QACpB,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,SAAS;QACrB,eAAe,EAAE,SAAS;QAC1B,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,SAAS;KAClB;IACD,MAAM,EAAE;QACN,EAAE,EAAE,CAAC;QACL,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,MAAM,EAAE,EAAE;KACX;IACD,OAAO,EAAE;QACP,EAAE,EAAE,CAAC;QACL,EAAE,EAAE,CAAC;QACL,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;KACP;IACD,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,EAAE;QACb,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,KAAK;KAClB;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ChatlyContextValue } from './ChatlyProvider';
2
+ export declare function useChatly(): ChatlyContextValue;
3
+ //# sourceMappingURL=useChatly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatly.d.ts","sourceRoot":"","sources":["../src/useChatly.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
@@ -0,0 +1,10 @@
1
+ import { useContext } from 'react';
2
+ import { ChatlyContext } from './ChatlyProvider';
3
+ export function useChatly() {
4
+ const ctx = useContext(ChatlyContext);
5
+ if (ctx === null) {
6
+ throw new Error('[@chatlychat/react-native] useChatly() must be called inside <ChatlyProvider>.');
7
+ }
8
+ return ctx;
9
+ }
10
+ //# sourceMappingURL=useChatly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatly.js","sourceRoot":"","sources":["../src/useChatly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,EAAE,aAAa,EAA2B,MAAM,kBAAkB,CAAC;AAE1E,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@chatlychat/react-native",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "React Native SDK for the Chatly live chat platform — drop-in chat, help center, and push notification wiring for iOS and Android.",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "sideEffects": false,
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.json",
16
+ "typecheck": "tsc --noEmit -p tsconfig.json",
17
+ "lint": "eslint src --max-warnings=0",
18
+ "test": "vitest run"
19
+ },
20
+ "keywords": [
21
+ "chatly",
22
+ "chat",
23
+ "messaging",
24
+ "support",
25
+ "react-native",
26
+ "sdk"
27
+ ],
28
+ "peerDependencies": {
29
+ "react": "^18",
30
+ "react-native": ">=0.73.0 <1.0.0",
31
+ "@react-native-async-storage/async-storage": "^2"
32
+ },
33
+ "dependencies": {
34
+ "socket.io-client": "^4.7.5"
35
+ },
36
+ "devDependencies": {
37
+ "@livechat/config": "workspace:*",
38
+ "@livechat/shared": "workspace:*",
39
+ "@testing-library/dom": "^10.4.1",
40
+ "@testing-library/react": "^16.3.2",
41
+ "@testing-library/user-event": "^14.5.2",
42
+ "@types/react": "^18",
43
+ "jsdom": "^30.0.1",
44
+ "react": "^18",
45
+ "react-dom": "^18",
46
+ "typescript": "^5.6",
47
+ "vitest": "catalog:"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }