Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ jobs:
runs-on: ubuntu-latest
services:
rumors-test-db:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2
image: elasticsearch:9.2.2
env:
discovery.type: single-node
xpack.security.enabled: 'false'
ports:
- 62223:9200

Expand All @@ -22,7 +25,7 @@ jobs:
submodules: true
- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: '24'
cache: 'npm'
- run: npm ci
- run: npm run lint
Expand Down
8 changes: 4 additions & 4 deletions hocuspocus-extension-elasticsearch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
"dist"
],
"dependencies": {
"@elastic/elasticsearch": "^6.8.6",
"@hocuspocus/extension-database": "^2.7.1",
"y-prosemirror": "^1.2.1",
"prosemirror-schema-basic": "^1.2.2"
"@elastic/elasticsearch": "^9.3.4",
"@hocuspocus/extension-database": "^3.4.4",
"prosemirror-schema-basic": "^1.2.2",
"y-prosemirror": "^1.3.7"
},
"devDependencies": {
"tslib": "^2.5.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
delayForMs,
} from 'test/utils';
import { Elasticsearch } from '../elasticsearch';
import elasticsearch from '@elastic/elasticsearch';
import { type ClientOptions } from '@elastic/elasticsearch';

describe('elasticsearch extension', () => {
const elasticsearchOpts: elasticsearch.ClientOptions = {
const elasticsearchOpts: ClientOptions = {
node: process.env.ELASTICSEARCH_URL,
};
afterEach(async () => {
Expand All @@ -19,7 +19,7 @@ describe('elasticsearch extension', () => {
it('return default ydoc when fetched documentName does not exist', async () => {
const server = await newHocuspocus({
yDocOptions: { gc: false, gcFilter: () => true },
port: process.env.PORT ? Number(process.env.PORT) : 1234,
port: 0,
extensions: [
new Elasticsearch({
elasticsearchOpts,
Expand All @@ -39,7 +39,7 @@ describe('elasticsearch extension', () => {
const textName = 'test_name';
const server = await newHocuspocus({
yDocOptions: { gc: false, gcFilter: () => true },
port: process.env.PORT ? Number(process.env.PORT) : 1234,
port: 0,
extensions: [
new Elasticsearch({
elasticsearchOpts,
Expand All @@ -64,7 +64,7 @@ describe('elasticsearch extension', () => {
jest.spyOn(global.console, 'error');
const server = await newHocuspocus({
yDocOptions: { gc: false, gcFilter: () => true },
port: 1234,
port: 0,

extensions: [
new Elasticsearch({
Expand All @@ -75,11 +75,11 @@ describe('elasticsearch extension', () => {
],
});
const provider = await syncedNewHocuspocusProvider(server);
expect(console.error).toBeCalledTimes(1);
expect(console.error).toHaveBeenCalled();
provider.configuration.websocketProvider.disconnect();
provider.disconnect();

// Note: console.error will be called again because onStoreDocument will be called as server cleanup
await server.destroy();
});
}, 30_000);
});
43 changes: 18 additions & 25 deletions hocuspocus-extension-elasticsearch/src/elasticsearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,33 @@ import {
Database,
DatabaseConfiguration,
} from '@hocuspocus/extension-database';
import elasticsearch from '@elastic/elasticsearch';
import { Client, type ClientOptions } from '@elastic/elasticsearch';

export interface ElasticsearchConfiguration extends DatabaseConfiguration {
elasticsearchOpts?: elasticsearch.ClientOptions;
elasticsearchOpts?: ClientOptions;
dbIndex?: string;
}

export class Elasticsearch extends Database {
db?: elasticsearch.Client;
db?: Client;
dbIndex: string;

configuration: ElasticsearchConfiguration = {
fetch: async ({ documentName }) => {
// console.log(`DB fetch ${documentName}`);
try {
/* istanbul ignore next */
const {
body: {
_source: { ydoc: data },
},
} =
(await this.db?.get({
index: this.dbIndex,
id: documentName,
type: 'doc',
})) || {};
const result = await this.db?.get<{ ydoc?: string }>({
index: this.dbIndex,
id: documentName,
});
const data = result?._source?.ydoc;
if (!data) return null;

return Buffer.from(data, 'base64');
} catch (e) {
// console.log(JSON.stringify(e));
if (e.meta.statusCode !== 404) {
if (e?.meta?.statusCode !== 404) {
console.error('[db]', e);
}
return null;
Expand All @@ -44,17 +40,14 @@ export class Elasticsearch extends Database {
/* istanbul ignore next */
await this.db?.update({
index: this.dbIndex,
type: 'doc',
id: documentName,
body: {
doc: {
// elasticsearch stores binary as a Base64 encoded string
// https://www.elastic.co/guide/en/elasticsearch/reference/current/binary.html
ydoc: state.toString('base64'),
},
upsert: {
ydoc: state.toString('base64'),
},
doc: {
// elasticsearch stores binary as a Base64 encoded string
// https://www.elastic.co/guide/en/elasticsearch/reference/current/binary.html
ydoc: state.toString('base64'),
},
upsert: {
ydoc: state.toString('base64'),
},
});
} catch (e) {
Expand All @@ -76,7 +69,7 @@ export class Elasticsearch extends Database {
const elasticsearchOpts = this.configuration.elasticsearchOpts || {
node: 'http://localhost:62222',
};
this.db = new elasticsearch.Client(elasticsearchOpts);
this.db = new Client(elasticsearchOpts);

this.dbIndex = this.configuration.dbIndex || 'ydocs';
}
Expand Down
Loading
Loading