Offline capabilities to Memos
Describe the solution you'd like
It would be interesting if when we lost internet connection we still had the app running normally doing local changes and then when back online sync thoses changes with the server.
Type of feature
User Experience (UX)
Additional context
This video might help with the development https://www.youtube.com/watch?v=1FMkFc4TIio
related: I'd like for drafts to get synced as they get typed to avoid losing them - even if just offline
I took a stab at this, but it is complicated by the fact that Memos uses gRPC-Web. gRPC-Web uses POST requests for everything which can't be cached in the native Cache objects without some manipulation. It looks like the server already exposes a REST API, so maybe we could switch to that?
I tried generating an API client using @openapitools/openapi-generator-cli and the openapi.yaml but some of the methods don't work correctly. For example GetWorkspaceSetting should take a string like "workspace/settings/GENERAL" and make a request to /api/v1/workspace/settings/GENERAL but instead it makes a request to /api/v1/workspace/workspace%2Fsettings%2FGENERAL/*. Note the URL encoding and trailing /*.
It seems like an issue with how the proto definition is translated to openapi.yaml.
rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {get: "/api/v1/{name=workspace/settings/*}"};
option (google.api.method_signature) = "name";
}
generates
/api/v1/workspace/{workspace}/*:
get:
tags:
- WorkspaceService
description: Gets a workspace setting.
operationId: WorkspaceService_GetWorkspaceSetting
parameters:
- name: workspace
in: path
description: The workspace id.
required: true
schema:
type: string
Maybe a bug in protoc-gen-openapi
I found the issue. protoc-gen-openai expects the path pattern to have alternating names and stars per this comment:
// The starred path is assumed to be in the form "things/*/otherthings/*".
// We want to convert it to "things/{thingsId}/otherthings/{otherthingsId}".
https://github.com/google/gnostic/blob/e0e09f70628157dc0db87ed60a109465ae62723b/cmd/protoc-gen-openapi/generator/generator.go#L508-L516
But our path looks like workspace/settings/*. This is why we're having to use google.api.method_signature and having to prepend /workspace/settings/ in the TS, because the generated path is wrong. I think if we change the proto to match the expectations, we'll get better results:
// Gets a workspace setting.
rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {get: "/api/v1/workspace/{name=settings/*}"};
option (google.api.method_signature) = "name";
}
This matches the example here: https://github.com/googleapis/googleapis/blob/f8776fec04e336527ba7279d960105533a1c4e21/google/api/http.proto#L68
@boojack Maybe you can lend some insight here. Is there a reason for including both workspace and settings in the name? I'm guessing that is trying to follow AIP guidance, but we're not following the recommendation of alternating collection/id/collection/id per https://google.aip.dev/122#guidance
I want to get the openapi.yaml correct so I can get offline mode working.
https://github.com/google/gnostic/pull/458 attempts a fix upstream, but I'm not sure it will be accepted