Skip to content

Commit

Permalink
feat(Web): Expose Document::create to web client
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome authored and alex-ketch committed Feb 16, 2022
1 parent 21978ac commit 79d4821
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 23 deletions.
2 changes: 1 addition & 1 deletion node/src/documents.rs
Expand Up @@ -19,7 +19,7 @@ pub fn create(mut cx: FunctionContext) -> JsResult<JsString> {
let path = not_empty_or_none(&cx.argument::<JsString>(0)?.value(&mut cx));
let format = not_empty_or_none(&cx.argument::<JsString>(1)?.value(&mut cx));

let result = RUNTIME.block_on(async { DOCUMENTS.create(path, format).await });
let result = RUNTIME.block_on(async { DOCUMENTS.create(path, None, format).await });
to_json_or_throw(cx, result)
}

Expand Down
29 changes: 24 additions & 5 deletions rust/stencila/src/documents.rs
Expand Up @@ -506,6 +506,22 @@ impl Document {
}
}

/// Create a new document, optionally with content.
pub async fn create<P: AsRef<Path>>(
path: Option<P>,
content: Option<String>,
format: Option<String>,
) -> Result<Document> {
let path = path.map(|path| PathBuf::from(path.as_ref()));

let mut document = Document::new(path, format);
if let Some(content) = content {
document.load(content, None).await?;
}

Ok(document)
}

/// Open a document from an existing file.
///
/// # Arguments
Expand Down Expand Up @@ -1693,11 +1709,14 @@ impl Documents {
Ok(paths)
}

/// Create a new empty document
pub async fn create(&self, path: Option<String>, format: Option<String>) -> Result<Document> {
let path = path.map(PathBuf::from);

let document = Document::new(path, format);
/// Create a new document
pub async fn create<P: AsRef<Path>>(
&self,
path: Option<P>,
content: Option<String>,
format: Option<String>,
) -> Result<Document> {
let document = Document::create(path, content, format).await?;
let document_id = document.id.clone();
let document_repr = document.repr();
let handler = DocumentHandler::new(document, false);
Expand Down
10 changes: 10 additions & 0 deletions rust/stencila/src/rpc.rs
Expand Up @@ -54,6 +54,7 @@ impl Request {
"sessions.subscribe" => sessions_subscribe(&self.params, client).await,
"sessions.unsubscribe" => sessions_unsubscribe(&self.params, client).await,
"kernels.languages" => kernels_languages(&self.params).await,
"documents.create" => documents_create(&self.params).await,
"documents.open" => documents_open(&self.params).await,
"documents.close" => documents_close(&self.params).await,
"documents.patch" => documents_patch(&self.params).await,
Expand Down Expand Up @@ -282,6 +283,15 @@ async fn kernels_languages(params: &Params) -> Result<(serde_json::Value, Subscr
Ok((json!(kernels), Subscription::None))
}

async fn documents_create(params: &Params) -> Result<(serde_json::Value, Subscription)> {
let path = optional_string(params, "path")?;
let content = optional_string(params, "content")?;
let format = optional_string(params, "format")?;

let document = DOCUMENTS.create(path, content, format).await?;
Ok((json!(document), Subscription::None))
}

async fn documents_open(params: &Params) -> Result<(serde_json::Value, Subscription)> {
let path = required_string(params, "path")?;

Expand Down
49 changes: 32 additions & 17 deletions web/src/documents.ts
Expand Up @@ -64,6 +64,21 @@ export interface ContentChangeEvent extends CustomEvent {
detail: ViewUpdate | string
}

/**
* Create a new document
*
* Optionally pass the content, in some format, for the new document.
*/
export async function create(
client: Client,
content?: string,
format?: string
): Promise<Document> {
return client.call('documents.create', {
content, format,
}) as Promise<Document>
}

/**
* Open a document
*
Expand Down Expand Up @@ -425,15 +440,15 @@ async function onContentChange(
*/
export interface ValidatorChangeEvent extends CustomEvent {
detail:
| {
type: 'property'
name: string
value: string
}
| {
type: 'validator'
value: Exclude<ValidatorTypes['type'], 'Validator'>
}
| {
type: 'property'
name: string
value: string
}
| {
type: 'validator'
value: Exclude<ValidatorTypes['type'], 'Validator'>
}
}

/**
Expand All @@ -450,16 +465,16 @@ async function onValidatorChange(
const [address, value]: [Address, JsonValue] =
event.detail.type === 'property'
? // The new validator property value
[
[
[
// ...except for `default` which is actually a property of the parent parameter
...(event.detail.name === 'default' ? [] : ['validator']),
event.detail.name,
],
event.detail.value,
]
// ...except for `default` which is actually a property of the parent parameter
...(event.detail.name === 'default' ? [] : ['validator']),
event.detail.name,
],
event.detail.value,
]
: // The new validator as an object with `type`
[['validator'], { type: event.detail.value }]
[['validator'], { type: event.detail.value }]

const op: Operation = {
type: 'Replace',
Expand Down

0 comments on commit 79d4821

Please sign in to comment.