@reactionary/source 0.0.28 → 0.0.30

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/trpc/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import superjson from 'superjson';
7
7
  import { z } from 'zod';
8
8
  import { BaseProvider } from '@reactionary/core';
9
9
  import { TRPCQueryProcedure, TRPCMutationProcedure } from '@trpc/server';
10
+ import { createTRPCTracing } from '@reactionary/otel';
10
11
 
11
12
  const t = initTRPC.context<{ client: Client; session: Session }>().create({
12
13
  transformer: superjson,
@@ -14,7 +15,10 @@ const t = initTRPC.context<{ client: Client; session: Session }>().create({
14
15
 
15
16
  export const router = t.router;
16
17
  export const mergeRouters = t.mergeRouters;
17
- export const publicProcedure = t.procedure;
18
+
19
+ // Always apply tracing middleware - exporters controlled via OTEL env vars
20
+ const basePublicProcedure = t.procedure;
21
+ export const publicProcedure = basePublicProcedure.use(createTRPCTracing());
18
22
 
19
23
  export function createTRPCRouter<T extends Client = Client>(client: T) {
20
24
  type BaseProviderKeys<T> = {
@@ -36,6 +40,8 @@ export function createTRPCRouter<T extends Client = Client>(client: T) {
36
40
  };
37
41
 
38
42
  const routes: Record<string, any> = {};
43
+ // Always enable tracing - exporters are controlled via env vars
44
+ const procedure = basePublicProcedure.use(createTRPCTracing());
39
45
 
40
46
  for (const key in client) {
41
47
  const provider = client[key];
@@ -44,14 +50,14 @@ export function createTRPCRouter<T extends Client = Client>(client: T) {
44
50
  const queryKey = key as keyof ReactionaryRouter;
45
51
  const mutationKey = key + 'Mutation' as keyof ReactionaryRouter;
46
52
 
47
- routes[queryKey] = publicProcedure
53
+ routes[queryKey] = procedure
48
54
  .input(provider.querySchema.array())
49
55
  .output(provider.schema.array())
50
56
  .query(async (opts) => {
51
57
  return provider.query(opts.input, opts.ctx.session);
52
58
  });
53
59
 
54
- routes[mutationKey] = publicProcedure
60
+ routes[mutationKey] = procedure
55
61
  .input(provider.mutationSchema.array())
56
62
  .output(provider.schema)
57
63
  .mutation(async (opts) => {
@@ -17,6 +17,7 @@
17
17
  "paths": {
18
18
  "@reactionary/core": ["core/src/index.ts"],
19
19
  "@reactionary/examples-node": ["examples/node/src/index.ts"],
20
+ "@reactionary/otel": ["otel/src/index.ts"],
20
21
  "@reactionary/provider-algolia": ["providers/algolia/src/index.ts"],
21
22
  "@reactionary/provider-commercetools": [
22
23
  "providers/commercetools/src/index.ts"
@@ -0,0 +1,4 @@
1
+ export default [
2
+ '**/vite.config.{mjs,js,ts,mts}',
3
+ '**/vitest.config.{mjs,js,ts,mts}',
4
+ ];
@@ -1,24 +0,0 @@
1
- import vue from 'eslint-plugin-vue';
2
- import baseConfig from '../../eslint.config.mjs';
3
-
4
- export default [
5
- ...baseConfig,
6
- ...vue.configs['flat/recommended'],
7
- {
8
- files: ['**/*.vue'],
9
- languageOptions: {
10
- parserOptions: {
11
- parser: await import('@typescript-eslint/parser'),
12
- },
13
- },
14
- },
15
- {
16
- files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.vue'],
17
- rules: {
18
- 'vue/multi-word-component-names': 'off',
19
- 'vue/html-self-closing': 'off',
20
- 'vue/max-attributes-per-line': 'off',
21
- 'vue/singleline-html-element-content-newline': 'off',
22
- },
23
- },
24
- ];
@@ -1,13 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" href="/favicon.ico" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>examples-vue</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.ts"></script>
12
- </body>
13
- </html>
@@ -1,8 +0,0 @@
1
- {
2
- "name": "examples-vue",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "projectType": "application",
5
- "sourceRoot": "examples/vue/src",
6
- "// targets": "to see all targets run: nx show project examples-vue --web",
7
- "targets": {}
8
- }
@@ -1,275 +0,0 @@
1
- <script setup lang="ts">
2
- import {
3
- buildClient,
4
- FacetValueIdentifier,
5
- SearchResult,
6
- } from '@reactionary/core';
7
- import { withAlgoliaCapabilities } from '@reactionary/provider-algolia';
8
- import { ref, watch, reactive, computed } from 'vue';
9
-
10
- const client = buildClient([
11
- withAlgoliaCapabilities(
12
- {
13
- apiKey: 'd67221c03e6e4b3bd47e1a35bfa46f36',
14
- appId: 'BPS0QU5YHD',
15
- indexName: 'products',
16
- },
17
- { search: true, product: true }
18
- ),
19
- ]);
20
-
21
- const result = ref<SearchResult | undefined>(undefined);
22
-
23
- const query = reactive({
24
- term: '',
25
- facets: new Array<FacetValueIdentifier>(),
26
- page: 0,
27
- pageSize: 20,
28
- });
29
-
30
- watch(
31
- query,
32
- async (q) => {
33
- result.value = await client.search.get({
34
- term: q.term,
35
- facets: q.facets,
36
- page: q.page,
37
- pageSize: q.pageSize,
38
- });
39
- },
40
- { immediate: true }
41
- );
42
-
43
- const hasNextPage = computed(() => {
44
- return query.page < (result.value?.pages || 0) - 1;
45
- });
46
-
47
- const hasPreviousPage = computed(() => {
48
- return query.page > 0;
49
- });
50
-
51
- function toggleFacet(value: FacetValueIdentifier) {
52
- const old = query.facets;
53
- const existingIndex = old.findIndex(
54
- (x) => JSON.stringify(x) === JSON.stringify(value)
55
- );
56
-
57
- if (existingIndex > -1) {
58
- query.facets.splice(existingIndex, 1);
59
- } else {
60
- query.facets.push(value);
61
- }
62
- }
63
-
64
- function updateTerm(e: Event) {
65
- if (e.target && e.target instanceof HTMLInputElement) {
66
- query.term = e.target.value;
67
- }
68
- }
69
- </script>
70
-
71
- <template>
72
- <div class="host">
73
- <header>
74
- <input @change="(event) => updateTerm(event)" />
75
- </header>
76
- <main>
77
- <aside>
78
- <details v-for="facet in result?.facets" :key="facet.identifier.key">
79
- <summary>
80
- {{ facet.name }}
81
- </summary>
82
- <div>
83
- <label
84
- v-for="value of facet.values"
85
- :key="value.identifier.key"
86
- >
87
- <span>{{ value.name }}</span>
88
- <span>{{ value.count }}</span>
89
- <input
90
- type="checkbox"
91
- :checked="value.active"
92
- @click="() => toggleFacet(value.identifier)"
93
- />
94
- </label>
95
- </div>
96
- </details>
97
- </aside>
98
- <section>
99
- <article
100
- v-for="product in result?.products"
101
- :key="product.identifier.key"
102
- >
103
- <img :src="product.image.replace('w_200', 'w_200,h_200')" />
104
- <h3>{{ product.name }}</h3>
105
- </article>
106
- </section>
107
- </main>
108
- <footer>
109
- <button :disabled="!hasPreviousPage" @click="() => query.page--">
110
- &lt;
111
- </button>
112
- <button :disabled="!hasNextPage" @click="() => query.page++">&gt;</button>
113
- </footer>
114
- </div>
115
- </template>
116
-
117
- <style lang="scss" scoped>
118
- .host {
119
- input,
120
- h3,
121
- button,
122
- a {
123
- all: unset;
124
- box-sizing: border-box;
125
- }
126
-
127
- header {
128
- width: 100%;
129
- padding: 0.5rem;
130
-
131
- input {
132
- padding-inline: 1rem;
133
- color: rgb(205, 214, 244);
134
- background: rgb(88, 91, 112);
135
- width: 100%;
136
- height: 3rem;
137
- border-radius: 0.5rem;
138
- }
139
- }
140
-
141
- main {
142
- padding-inline: 0.5rem;
143
- display: grid;
144
- gap: 0.5rem;
145
- grid-template-columns: 300px 1fr;
146
- color: rgb(205, 214, 244);
147
- }
148
-
149
- details[open] {
150
- summary:after {
151
- content: '-';
152
- }
153
- }
154
-
155
- details {
156
- position: relative;
157
- background: rgb(49, 50, 68);
158
- border-radius: 0.5rem;
159
- }
160
-
161
- summary {
162
- font-weight: bold;
163
- text-transform: capitalize;
164
- list-style: none;
165
- padding: 0.5rem;
166
-
167
- &::-webkit-details-marker {
168
- display: none;
169
- }
170
-
171
- &::after {
172
- position: absolute;
173
- top: 0.5rem;
174
- right: 0.5rem;
175
- content: '+';
176
- line-height: 1;
177
- }
178
- }
179
-
180
- aside {
181
- display: grid;
182
- grid-template-columns: 1fr;
183
- grid-auto-rows: min-content;
184
- gap: 0.25rem;
185
-
186
- div {
187
- display: grid;
188
- grid-template-columns: 1fr min-content min-content;
189
- grid-auto-rows: min-content;
190
- padding: 0.5rem;
191
- gap: 0.5rem;
192
-
193
- a {
194
- display: contents;
195
- }
196
-
197
- label {
198
- grid-column: span 3;
199
- display: grid;
200
- grid-template-columns: subgrid;
201
- align-items: center;
202
- gap: 0.5rem;
203
-
204
- input {
205
- width: 1.5rem;
206
- height: 1.5rem;
207
- background: rgb(147, 153, 178);
208
- border-radius: 0.125rem;
209
-
210
- &:checked {
211
- background: rgb(137, 220, 235);
212
- }
213
- }
214
- }
215
- }
216
- }
217
-
218
- section {
219
- justify-content: center;
220
- display: grid;
221
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
222
- grid-auto-rows: min-content;
223
- gap: 0.5rem;
224
- }
225
-
226
- article {
227
- background: rgb(49, 50, 68);
228
- border-radius: 0.25rem;
229
- display: grid;
230
- grid-template-columns: 1fr;
231
- grid-template-rows: 1fr min-content;
232
- gap: 1rem;
233
-
234
- h3 {
235
- line-height: 1.2;
236
- font-size: 1rem;
237
- text-align: center;
238
- margin-bottom: 1rem;
239
- }
240
-
241
- img {
242
- object-fit: contain;
243
- border-top-left-radius: inherit;
244
- border-top-right-radius: inherit;
245
- max-width: 100%;
246
- width: 100%;
247
- }
248
- }
249
-
250
- footer {
251
- margin: 0.5rem;
252
- gap: 0.25rem;
253
- display: grid;
254
- grid-template-columns: min-content min-content;
255
- align-items: center;
256
- justify-content: center;
257
- }
258
-
259
- button {
260
- display: grid;
261
- justify-content: center;
262
- align-items: center;
263
-
264
- height: 3rem;
265
- background: rgb(49, 50, 68);
266
- color: rgb(205, 214, 244);
267
- aspect-ratio: 1 / 1;
268
- border-radius: 0.25rem;
269
-
270
- &:disabled {
271
- opacity: 0.5;
272
- }
273
- }
274
- }
275
- </style>
@@ -1,6 +0,0 @@
1
- import './styles.scss';
2
- import { createApp } from 'vue';
3
- import App from './app/App.vue';
4
-
5
- const app = createApp(App);
6
- app.mount('#root');
@@ -1,9 +0,0 @@
1
- * {
2
- box-sizing: border-box;
3
- }
4
-
5
- body {
6
- margin: 0;
7
- padding: 0;
8
- background: rgb(17, 17, 27);
9
- }
@@ -1,5 +0,0 @@
1
- declare module '*.vue' {
2
- import { defineComponent } from 'vue';
3
- const component: ReturnType<typeof defineComponent>;
4
- export default component;
5
- }
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../dist/out-tsc",
5
- "types": ["vite/client"]
6
- },
7
- "exclude": [
8
- "src/**/*.spec.ts",
9
- "src/**/*.test.ts",
10
- "src/**/*.spec.vue",
11
- "src/**/*.test.vue"
12
- ],
13
- "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.vue"]
14
- }
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "esModuleInterop": false,
5
- "allowSyntheticDefaultImports": true,
6
- "strict": true,
7
- "jsx": "preserve",
8
- "jsxImportSource": "vue",
9
- "moduleResolution": "node",
10
- "resolveJsonModule": true
11
- },
12
- "files": [],
13
- "include": [],
14
- "references": [
15
- {
16
- "path": "./tsconfig.app.json"
17
- }
18
- ],
19
- "extends": "../../tsconfig.base.json"
20
- }
@@ -1,31 +0,0 @@
1
- /// <reference types='vitest' />
2
- import { defineConfig } from 'vite';
3
- import vue from '@vitejs/plugin-vue';
4
- import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
5
- import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
6
-
7
- export default defineConfig(() => ({
8
- root: __dirname,
9
- cacheDir: '../../node_modules/.vite/examples/vue',
10
- server: {
11
- port: 4200,
12
- host: 'localhost',
13
- },
14
- preview: {
15
- port: 4300,
16
- host: 'localhost',
17
- },
18
- plugins: [vue(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
19
- // Uncomment this if you are using workers.
20
- // worker: {
21
- // plugins: [ nxViteTsPaths() ],
22
- // },
23
- build: {
24
- outDir: '../../dist/examples/vue',
25
- emptyOutDir: true,
26
- reportCompressedSize: true,
27
- commonjsOptions: {
28
- transformMixedEsModules: true,
29
- },
30
- },
31
- }));