@fluid-topics/public-api 1.0.56 → 1.0.58

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.
@@ -0,0 +1,54 @@
1
+ import { expect } from "@open-wc/testing"
2
+ import { GenAIChunkReader } from "../../src/helpers/GenAIChunkReader"
3
+
4
+ class FakeStream implements ReadableStreamDefaultReader<Uint8Array> {
5
+ readonly closed: Promise<undefined>
6
+ readonly encoder = new TextEncoder()
7
+
8
+ constructor(readonly chunks: string[]) {
9
+ }
10
+
11
+ cancel(reason?: any): Promise<void> {
12
+ return Promise.resolve(undefined)
13
+ }
14
+
15
+ read() {
16
+ if (this.chunks.length === 0) {
17
+ return Promise.resolve({ done: true, value: undefined })
18
+ }
19
+ const chunk = this.chunks.shift()
20
+ let value: Uint8Array = this.encoder.encode(chunk)
21
+ return Promise.resolve({ done: false, value })
22
+ }
23
+
24
+ releaseLock(): void {
25
+ }
26
+
27
+ }
28
+
29
+ describe(GenAIChunkReader.name, () => {
30
+ it("should wait for complete chunks", async () => {
31
+ const stream = new FakeStream([
32
+ `data:{`,
33
+ `"foo`,
34
+ `":"bar"}\n`,
35
+ `data:{"foo":"quz"}\n`
36
+ ])
37
+ const generator = new GenAIChunkReader(stream).read()
38
+
39
+ expect((await generator.next()).value).to.deep.equal({ "foo": "bar" })
40
+ expect((await generator.next()).value).to.deep.equal({ "foo": "quz" })
41
+ expect((await generator.next()).done).to.be.true
42
+ })
43
+
44
+ it("should ignore non-data chunks", async () => {
45
+ const stream = new FakeStream([
46
+ `patate:{"foo":"bar"}\n`,
47
+ `data:{"foo":"quz"}\n`
48
+ ])
49
+ const generator = new GenAIChunkReader(stream).read()
50
+
51
+ expect((await generator.next()).value).to.deep.equal({ "foo": "quz" })
52
+ expect((await generator.next()).done).to.be.true
53
+ })
54
+ })
@@ -0,0 +1,95 @@
1
+ import http from "node:http"
2
+ import {existsSync} from "node:fs"
3
+ import {createServer} from "vite"
4
+
5
+ const callWithFileNames = (callback) => ({
6
+ name: "file-name",
7
+ transform(src, id) {
8
+ callback(id)
9
+ },
10
+ })
11
+
12
+ const markExternal = (options) => ({
13
+ name: "mark-external",
14
+ resolveId(path) {
15
+ if (!options.includes(path)) {
16
+ return
17
+ }
18
+
19
+ return {
20
+ id: path,
21
+ external: true
22
+ }
23
+ },
24
+ })
25
+
26
+ const get = url => new Promise((resolve, reject) => {
27
+ const request = http.get(url, (response) => {
28
+ const buffers = []
29
+ let bufferLen = 0
30
+
31
+ response.on("data", chunk => {
32
+ bufferLen += chunk.length
33
+ buffers.push(chunk)
34
+ })
35
+
36
+ response.on("end", () => resolve({
37
+ body: Buffer.concat(buffers, bufferLen),
38
+ headers: response.headers,
39
+ status: response.statusCode,
40
+ }))
41
+ })
42
+
43
+ request.on("error", (err) => reject(err))
44
+ })
45
+
46
+ const proxy = (url) => async ctx => {
47
+ const {body, headers, status} = await get(url + ctx.originalUrl)
48
+ ctx.set(headers)
49
+ ctx.body = body
50
+ ctx.status = status
51
+ }
52
+
53
+ export const vitePlugin = (conf) => {
54
+ let viteServer
55
+
56
+ return {
57
+ name: "vite-plugin",
58
+
59
+ async serverStart({app, fileWatcher}) {
60
+ const plugins = [
61
+ callWithFileNames(id => {
62
+ const file = id.split("?")[0]
63
+ if (!file.startsWith("\0") && existsSync(file)) {
64
+ fileWatcher.add(id)
65
+ }
66
+ }),
67
+ markExternal([
68
+ /* @web/test-runner-commands needs to establish a web-socket
69
+ * connection. It expects a file to be served from the
70
+ * @web/dev-server. So it should be ignored by Vite */
71
+ "/__web-dev-server__web-socket.js",
72
+ ]),
73
+ ]
74
+
75
+ viteServer = await createServer({
76
+ clearScreen: false,
77
+ plugins,
78
+ /* Disable hmr in favor of the @web/test-runner to take care of
79
+ * restarts. */
80
+ server: {hmr: false},
81
+ ...conf
82
+ })
83
+ await viteServer.listen()
84
+
85
+ const vitePort = viteServer.config.server.port
86
+ const viteProtocol = viteServer.config.server.https ? "https" : "http"
87
+
88
+ app.use(proxy(`${viteProtocol}://localhost:${vitePort}`))
89
+ },
90
+
91
+ async serverStop() {
92
+ return viteServer.close()
93
+ },
94
+ }
95
+ }
@@ -0,0 +1,58 @@
1
+ import {playwrightLauncher} from '@web/test-runner-playwright';
2
+ import {defaultReporter} from "@web/test-runner";
3
+ import {junitReporter} from "@web/test-runner-junit-reporter";
4
+ import {vitePlugin} from "./vite-plugin.mjs";
5
+
6
+ const ignoredLogs = [
7
+ "[vite] connecting...",
8
+ "[vite] connected.",
9
+ "Lit is in dev mode.",
10
+ "Multiple versions of Lit loaded.",
11
+ "Fluid Topics public API was not found.",
12
+ "scheduled an update (generally because a property was set) after an update completed",
13
+ ]
14
+
15
+ export default {
16
+ rootDir: '.',
17
+ files: ['./test-browser/**/*.test.ts'],
18
+ nodeResolve: true,
19
+ preserveSymlinks: true,
20
+ browsers: [
21
+ playwrightLauncher({product: 'chromium'}),
22
+ ],
23
+ reporters: [
24
+ defaultReporter({reportTestResults: true, reportTestProgress: true}),
25
+ junitReporter({
26
+ outputPath: './build/test-results/web-components.xml',
27
+ reportLogs: true,
28
+ }),
29
+ ],
30
+ plugins: [
31
+ vitePlugin({
32
+ optimizeDeps: {
33
+ disabled: true
34
+ }
35
+ }),
36
+ {
37
+ name: "cross-fetch-plugin",
38
+ async serve(context) {
39
+ if (context.path.includes("cross-fetch")) {
40
+ return `export default {}`;
41
+ }
42
+ }
43
+ },
44
+ ],
45
+ filterBrowserLogs: (log) => !(typeof log.args[0] === "string" && ignoredLogs.some(l => log.args[0].includes(l))),
46
+ testRunnerHtml: (testRunnerImport) => `
47
+ <html>
48
+ <body>
49
+ <script type="module">
50
+ window.process = { env: { NODE_ENV: 'test' } };
51
+ </script>
52
+ <script type="module">
53
+ import '${testRunnerImport}';
54
+ </script>
55
+ </body>
56
+ </html>
57
+ `,
58
+ };