@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.
- package/build/cjs/helpers/GenAIChunkReader.js +66 -0
- package/build/cjs/index.js +43 -0
- package/build/cjs/types/ft-common/public.js +3 -1
- package/build/cjs/types/ft-server/public.js +3 -1
- package/build/mjs/helpers/GenAIChunkReader.d.ts +15 -0
- package/build/mjs/helpers/GenAIChunkReader.js +37 -0
- package/build/mjs/index.d.ts +5 -0
- package/build/mjs/index.js +17 -0
- package/build/mjs/types/ft-common/public.d.ts +2 -0
- package/build/mjs/types/ft-common/public.js +3 -1
- package/build/mjs/types/ft-server/public.d.ts +2 -0
- package/build/mjs/types/ft-server/public.js +3 -1
- package/build/rollup/fluidtopics.min.js +1 -1
- package/build/test-results/web-components.xml +12 -0
- package/dist/cjs/helpers/GenAIChunkReader.js +66 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/types/ft-common/public.js +3 -1
- package/dist/cjs/types/ft-server/public.js +3 -1
- package/dist/fluidtopics.min.js +1 -1
- package/dist/mjs/helpers/GenAIChunkReader.d.ts +15 -0
- package/dist/mjs/helpers/GenAIChunkReader.js +37 -0
- package/dist/mjs/index.d.ts +5 -0
- package/dist/mjs/index.js +17 -0
- package/dist/mjs/types/ft-common/public.d.ts +2 -0
- package/dist/mjs/types/ft-common/public.js +3 -1
- package/dist/mjs/types/ft-server/public.d.ts +2 -0
- package/dist/mjs/types/ft-server/public.js +3 -1
- package/package.json +7 -2
- package/test-browser/helpers/GenAIChunkReader.test.ts +54 -0
- package/vite-plugin.mjs +95 -0
- package/web-test-runner.config.mjs +58 -0
|
@@ -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
|
+
})
|
package/vite-plugin.mjs
ADDED
|
@@ -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
|
+
};
|